Lint-staged: Error: `/bin/sh: [filepath]: Permission denied`

Created on 13 Apr 2020  ยท  13Comments  ยท  Source: okonet/lint-staged

Description

An error of type /bin/sh: [filepath]: Permission denied happens when executing lint-staged from the root folder on files located in a subfolder.

I have a root folder with two subfolders. Each subfolder has the linting and formatting packages and configurations. The root folder has Husky and lint-staged.

    .
    โ”œโ”€โ”€ backend
    โ”‚    โ”œโ”€โ”€ (config files for backend folder)
    โ”‚    โ”œโ”€โ”€ node_modules (includes ESLint and Prettier)
    โ”‚    โ”œโ”€โ”€ package-lock.json
    โ”‚    โ””โ”€โ”€ package.json
    โ”œโ”€โ”€ frontend
    โ”‚    โ”œโ”€โ”€ (config files for frontend folder)
    โ”‚    โ”œโ”€โ”€ node_modules (includes ESLint and Prettier)
    โ”‚    โ”œโ”€โ”€ package-lock.json
    โ”‚    โ””โ”€โ”€ package.json
    โ”œโ”€โ”€ node_modules (includes Husky and lint-staged)
    โ”œโ”€โ”€ package-lock.json
    โ””โ”€โ”€ package.json

In the root folder package.json I have the following scripts:

"scripts": {
    "lint": "concurrently \"cd backend && npm run lint\" \"cd frontend && npm run lint\"",
    "format": "concurrently \"cd backend && npm run format\" \"cd frontend && npm run format\""
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "(backend|frontend)/**/*.{js,jsx,ts,tsx}": ["npm run lint"],
    "(backend|frontend)/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}": ["npm run format"]
  },

Running npm run lint or npm run format in the terminal works correctly, but they fail when running with lint staged.

I tried to solve it by following the process for multi package repos without Lerna, but no luck.

Debug Logs


expand to view

husky > pre-commit (node v13.12.0)
  lint-staged:bin Running `[email protected]` +0ms
  lint-staged:bin Options parsed from command-line: {
  allowEmpty: false,
  concurrent: true,
  configPath: undefined,
  debug: true,
  maxArgLength: 131072,
  stash: true,
  quiet: false,
  relative: false,
  shell: false
} +1ms
  lint-staged Loading config using `cosmiconfig` +0ms
  lint-staged Successfully loaded config from `/Users/lllobera/Documents/lewis/plants-almanac/package.json`:
  lint-staged {
  lint-staged   '(backend|frontend)/**/*.{js,jsx,ts,tsx}': [ 'npm run lint' ],
  lint-staged   '(backend|frontend)/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}': [ 'npm run format' ]
  lint-staged } +10ms
  lint-staged:cfg Validating config +0ms
Running lint-staged with the following config:
{
  '(backend|frontend)/**/*.{js,jsx,ts,tsx}': [
    'npm run lint'
  ],
  '(backend|frontend)/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}': [
    'npm run format'
  ]
}
  lint-staged Unset GIT_LITERAL_PATHSPECS (was `undefined`) +2ms
  lint-staged:run Running all linter scripts +0ms
  lint-staged:resolveGitRepo Resolving git repo from `/Users/lllobera/Documents/lewis/plants-almanac` +0ms
  lint-staged:resolveGitRepo Unset GIT_DIR (was `undefined`) +0ms
  lint-staged:git Running git command [ 'rev-parse', '--show-toplevel' ] +0ms
  lint-staged:resolveGitRepo Resolved git directory to be `/Users/lllobera/Documents/lewis/plants-almanac` +11ms
  lint-staged:resolveGitRepo Resolved git config directory to be `/Users/lllobera/Documents/lewis/plants-almanac/.git` +0ms
  lint-staged:git Running git command [ 'diff', '--staged', '--diff-filter=ACMR', '--name-only', '-z' ] +11ms
  lint-staged:run Loaded list of staged files in git:
  lint-staged:run [ 'frontend/package.json' ] +20ms
  lint-staged:chunkFiles Resolved an argument string length of 68 characters from 1 files +0ms
  lint-staged:chunkFiles Creating 1 chunks for maxArgLength of 131072 +0ms
  lint-staged:gen-tasks Generating linter tasks +0ms
  lint-staged:gen-tasks Generated task: 
  lint-staged:gen-tasks {
  lint-staged:gen-tasks   pattern: '(backend|frontend)/**/*.{js,jsx,ts,tsx}',
  lint-staged:gen-tasks   commands: [ 'npm run lint' ],
  lint-staged:gen-tasks   fileList: []
  lint-staged:gen-tasks } +3ms
  lint-staged:gen-tasks Generated task: 
  lint-staged:gen-tasks {
  lint-staged:gen-tasks   pattern: '(backend|frontend)/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}',
  lint-staged:gen-tasks   commands: [ 'npm run format' ],
  lint-staged:gen-tasks   fileList: [
  lint-staged:gen-tasks     '/Users/lllobera/Documents/lewis/plants-almanac/frontend/package.json'
  lint-staged:gen-tasks   ]
  lint-staged:gen-tasks } +1ms
  lint-staged:make-cmd-tasks Creating listr tasks for commands [ 'npm run lint' ] +0ms
  lint-staged:task cmd: npm +0ms
  lint-staged:task args: [ 'run', 'lint' ] +0ms
  lint-staged:task execaOptions: { preferLocal: true, reject: false, shell: false } +0ms
  lint-staged:make-cmd-tasks Creating listr tasks for commands [ 'npm run format' ] +1ms
  lint-staged:task cmd: npm +0ms
  lint-staged:task args: [ 'run', 'format' ] +0ms
  lint-staged:task execaOptions: { preferLocal: true, reject: false, shell: false } +0ms
Preparing... [started]
  lint-staged:git Backing up original state... +0ms
  lint-staged:git Getting partially staged files... +0ms
  lint-staged:git Running git command [ 'status', '--porcelain' ] +18ms
  lint-staged:git Found partially staged files: [] +14ms
  lint-staged:git Getting deleted files... +0ms
  lint-staged:git Running git command [ 'ls-files', '--deleted' ] +14ms
  lint-staged:git Found deleted files: [] +9ms
  lint-staged:git Backing up merge state... +0ms
  lint-staged:file Reading file `/Users/lllobera/Documents/lewis/plants-almanac/.git/MERGE_HEAD` +0ms
  lint-staged:file Reading file `/Users/lllobera/Documents/lewis/plants-almanac/.git/MERGE_MODE` +0ms
  lint-staged:file Reading file `/Users/lllobera/Documents/lewis/plants-almanac/.git/MERGE_MSG` +1ms
  lint-staged:file File `/Users/lllobera/Documents/lewis/plants-almanac/.git/MERGE_HEAD` doesn't exist, ignoring... +0ms
  lint-staged:file File `/Users/lllobera/Documents/lewis/plants-almanac/.git/MERGE_MODE` doesn't exist, ignoring... +0ms
  lint-staged:file File `/Users/lllobera/Documents/lewis/plants-almanac/.git/MERGE_MSG` doesn't exist, ignoring... +0ms
  lint-staged:git Done backing up merge state! +1ms
  lint-staged:git Running git command [ 'stash', 'save', 'lint-staged automatic backup' ] +10ms
  lint-staged:git Running git command [ 'stash', 'list' ] +51ms
  lint-staged:git Running git command [ 'stash', 'apply', '--quiet', '--index', 'stash@{0}' ] +20ms
  lint-staged:git Restoring merge state... +132ms
  lint-staged:git Done restoring merge state! +0ms
  lint-staged:git Done backing up original state! +0ms
Preparing... [completed]
Running tasks... [started]
Running tasks for (backend|frontend)/**/*.{js,jsx,ts,tsx} [started]
Running tasks for (backend|frontend)/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql} [started]
Running tasks for (backend|frontend)/**/*.{js,jsx,ts,tsx} [skipped]
โ†’ No staged files match (backend|frontend)/**/*.{js,jsx,ts,tsx}
npm run format [started]
npm run format [failed]
โ†’ 
Running tasks for (backend|frontend)/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql} [failed]
โ†’ 
Running tasks... [failed]
Applying modifications... [started]
Applying modifications... [skipped]
โ†’ Skipped because of errors from tasks.
Reverting to original state because of errors... [started]
  lint-staged:git Restoring original state... +2s
  lint-staged:git Running git command [ 'reset', '--hard', 'HEAD' ] +2s
  lint-staged:git Running git command [ 'stash', 'list' ] +21ms
  lint-staged:git Running git command [ 'stash', 'apply', '--quiet', '--index', 'stash@{0}' ] +24ms
  lint-staged:git Restoring merge state... +112ms
  lint-staged:git Done restoring merge state! +0ms
  lint-staged:git Done restoring original state! +0ms
Reverting to original state because of errors... [completed]
Cleaning up... [started]
  lint-staged:git Dropping backup stash... +1ms
  lint-staged:git Running git command [ 'stash', 'list' ] +68ms
  lint-staged:git Running git command [ 'stash', 'drop', '--quiet', 'stash@{0}' ] +26ms
  lint-staged:git Done dropping backup stash! +61ms
Cleaning up... [completed]



โœ– npm found some errors. Please fix them and try committing again.

> [email protected] format /Users/lllobera/Documents/lewis/plants-almanac
> concurrently "cd backend && npm run format" "cd frontend && npm run format" "/Users/lllobera/Documents/lewis/plants-almanac/frontend/package.json"

[2] /bin/sh: /Users/lllobera/Documents/lewis/plants-almanac/frontend/package.json: Permission denied
[2] /Users/lllobera/Documents/lewis/plants-almanac/frontend/package.json exited with code 126
[0] 
[0] > @plants-almanac/[email protected] format /Users/lllobera/Documents/lewis/plants-almanac/backend
[0] > prettier --write --check "{,!(.cache|dist|node_modules)/**/}*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}"
[0] 
[1] 
[1] > @plants-almanac/[email protected] format /Users/lllobera/Documents/lewis/plants-almanac/frontend
[1] > prettier --write --check "{,!(.cache|dist|node_modules)/**/}*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}" "!src/graphql/types/**"
[1] 
[0] Checking formatting...
[1] Checking formatting...
[0] All matched files use Prettier code style!
[0] cd backend && npm run format exited with code 0
[1] src/index.html
[1] Code style issues fixed in the above file(s).
[1] cd frontend && npm run format exited with code 0
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] format: `concurrently "cd backend && npm run format" "cd frontend && npm run format" "/Users/lllobera/Documents/lewis/plants-almanac/frontend/package.json"`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] format script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/lllobera/.npm/_logs/2020-04-13T11_20_10_178Z-debug.log
husky > pre-commit hook failed (add --no-verify to bypass)

Environment

  • OS: macOS Catalina 10.15.4
  • Node.js: v13.12.0
  • lint-staged: 10.1.3

Most helpful comment

I found the issue mate. It's because of concurrently. when concurrently runs one script for the file, that file gets locked and another script can't be run with lint-staged.
I replaced
"lint": "concurrently \"cd backend && npm run lint\" \"cd frontend && npm run lint\"",
with
"backend-lint": "npm run lint-backend-fix --prefix backend",

and add lint-backend-fix script in backend/package.json
"lint-backend-fix": "npm run lint && npm run format"

and do the similar with frontend
change lint-staged with only two scripts, like backend-lint and frontend-fix

All 13 comments

I'm getting the same issue.

@lewislbr did you find the solution please?

From the logs, this command looks problematic:

prettier --write --check "{,!(.cache|dist|node_modules)/**/}*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}" "!src/graphql/types/**"

@lewislbr , If you don't commit and run manually npm run lint or npm run format does it work for you? I mean does it run linting and prettier?

@nirvparekh Still no solution. Without committing, if I run npm run lint or npm run format from the root folder they work.

@iiroj Those commands work correctly when running them, I cleaned them up a bit but the same error happens:


expand to view

husky > pre-commit (node v13.13.0)
  lint-staged:bin Running `[email protected]` +0ms
  lint-staged:bin Options parsed from command-line: {
  allowEmpty: false,
  concurrent: true,
  configPath: undefined,
  debug: true,
  maxArgLength: 131072,
  stash: true,
  quiet: false,
  relative: false,
  shell: false
} +1ms
  lint-staged Loading config using `cosmiconfig` +0ms
  lint-staged Successfully loaded config from `/Users/lllobera/Documents/lewis/plants-almanac/package.json`:
  lint-staged {
  lint-staged   '(backend|frontend)/**/*.{js,jsx,ts,tsx}': [ 'npm run lint' ],
  lint-staged   '(backend|frontend)/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}': [ 'npm run format' ]
  lint-staged } +9ms
  lint-staged:cfg Validating config +0ms
Running lint-staged with the following config:
{
  '(backend|frontend)/**/*.{js,jsx,ts,tsx}': [
    'npm run lint'
  ],
  '(backend|frontend)/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}': [
    'npm run format'
  ]
}
  lint-staged Unset GIT_LITERAL_PATHSPECS (was `undefined`) +2ms
  lint-staged:run Running all linter scripts +0ms
  lint-staged:resolveGitRepo Resolving git repo from `/Users/lllobera/Documents/lewis/plants-almanac` +0ms
  lint-staged:resolveGitRepo Unset GIT_DIR (was `undefined`) +0ms
  lint-staged:git Running git command [ 'rev-parse', '--show-toplevel' ] +0ms
  lint-staged:resolveGitRepo Resolved git directory to be `/Users/lllobera/Documents/lewis/plants-almanac` +11ms
  lint-staged:resolveGitRepo Resolved git config directory to be `/Users/lllobera/Documents/lewis/plants-almanac/.git` +0ms
  lint-staged:git Running git command [ 'log', '-1' ] +10ms
  lint-staged:git Running git command [ 'diff', '--staged', '--diff-filter=ACMR', '--name-only', '-z' ] +8ms
  lint-staged:run Loaded list of staged files in git:
  lint-staged:run [ 'frontend/src/components/index.ts' ] +26ms
  lint-staged:chunkFiles Resolved an argument string length of 79 characters from 1 files +0ms
  lint-staged:chunkFiles Creating 1 chunks for maxArgLength of 131072 +0ms
  lint-staged:gen-tasks Generating linter tasks +0ms
  lint-staged:gen-tasks Generated task: 
  lint-staged:gen-tasks {
  lint-staged:gen-tasks   pattern: '(backend|frontend)/**/*.{js,jsx,ts,tsx}',
  lint-staged:gen-tasks   commands: [ 'npm run lint' ],
  lint-staged:gen-tasks   fileList: [
  lint-staged:gen-tasks     '/Users/lllobera/Documents/lewis/plants-almanac/frontend/src/components/index.ts'
  lint-staged:gen-tasks   ]
  lint-staged:gen-tasks } +3ms
  lint-staged:gen-tasks Generated task: 
  lint-staged:gen-tasks {
  lint-staged:gen-tasks   pattern: '(backend|frontend)/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}',
  lint-staged:gen-tasks   commands: [ 'npm run format' ],
  lint-staged:gen-tasks   fileList: [
  lint-staged:gen-tasks     '/Users/lllobera/Documents/lewis/plants-almanac/frontend/src/components/index.ts'
  lint-staged:gen-tasks   ]
  lint-staged:gen-tasks } +1ms
  lint-staged:make-cmd-tasks Creating listr tasks for commands [ 'npm run lint' ] +0ms
  lint-staged:task cmd: npm +0ms
  lint-staged:task args: [ 'run', 'lint' ] +0ms
  lint-staged:task execaOptions: { preferLocal: true, reject: false, shell: false } +0ms
  lint-staged:make-cmd-tasks Creating listr tasks for commands [ 'npm run format' ] +1ms
  lint-staged:task cmd: npm +0ms
  lint-staged:task args: [ 'run', 'format' ] +0ms
  lint-staged:task execaOptions: { preferLocal: true, reject: false, shell: false } +0ms
Preparing... [started]
  lint-staged:git Backing up original state... +0ms
  lint-staged:git Getting partially staged files... +0ms
  lint-staged:git Running git command [ 'status', '--porcelain' ] +17ms
  lint-staged:git Found partially staged files: [] +11ms
  lint-staged:git Backing up merge state... +0ms
  lint-staged:file Reading file `/Users/lllobera/Documents/lewis/plants-almanac/.git/MERGE_HEAD` +0ms
  lint-staged:file Reading file `/Users/lllobera/Documents/lewis/plants-almanac/.git/MERGE_MODE` +0ms
  lint-staged:file Reading file `/Users/lllobera/Documents/lewis/plants-almanac/.git/MERGE_MSG` +1ms
  lint-staged:file File `/Users/lllobera/Documents/lewis/plants-almanac/.git/MERGE_HEAD` doesn't exist, ignoring... +0ms
  lint-staged:file File `/Users/lllobera/Documents/lewis/plants-almanac/.git/MERGE_MODE` doesn't exist, ignoring... +0ms
  lint-staged:file File `/Users/lllobera/Documents/lewis/plants-almanac/.git/MERGE_MSG` doesn't exist, ignoring... +0ms
  lint-staged:git Done backing up merge state! +1ms
  lint-staged:git Getting deleted files... +0ms
  lint-staged:git Running git command [ 'ls-files', '--deleted' ] +12ms
  lint-staged:git Found deleted files: [
  '/Users/lllobera/Documents/lewis/plants-almanac/frontend/src/components/PlantCard.tsx'
] +7ms
  lint-staged:git Running git command [ 'stash', 'create' ] +7ms
  lint-staged:git Running git command [
  'stash',
  'store',
  '--quiet',
  '--message',
  'lint-staged automatic backup',
  '10651e93425c47cf562012eb6fa1fa63eb69a6f7'
] +44ms
  lint-staged:git Done backing up original state! +58ms
Preparing... [completed]
Running tasks... [started]
Running tasks for (backend|frontend)/**/*.{js,jsx,ts,tsx} [started]
Running tasks for (backend|frontend)/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql} [started]
npm run lint [started]
npm run format [started]
npm run format [failed]
โ†’ 
Running tasks for (backend|frontend)/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql} [failed]
โ†’ 
npm run lint [failed]
โ†’ 
Running tasks for (backend|frontend)/**/*.{js,jsx,ts,tsx} [failed]
โ†’ 
Running tasks... [failed]
Applying modifications... [started]
Applying modifications... [skipped]
โ†’ Skipped because of errors from tasks.
Reverting to original state because of errors... [started]
  lint-staged:git Restoring original state... +2s
  lint-staged:git Running git command [ 'reset', '--hard', 'HEAD' ] +2s
  lint-staged:git Running git command [ 'stash', 'list' ] +21ms
  lint-staged:git Running git command [ 'stash', 'apply', '--quiet', '--index', 'stash@{0}' ] +15ms
  lint-staged:git Restoring merge state... +129ms
  lint-staged:git Done restoring merge state! +0ms
  lint-staged:file Removing file `/Users/lllobera/Documents/lewis/plants-almanac/frontend/src/components/PlantCard.tsx` +2s
  lint-staged:file File `/Users/lllobera/Documents/lewis/plants-almanac/frontend/src/components/PlantCard.tsx` doesn't exist, ignoring... +1ms
  lint-staged:file Removing file `/Users/lllobera/Documents/lewis/plants-almanac/.git/lint-staged_unstaged.patch` +0ms
  lint-staged:file File `/Users/lllobera/Documents/lewis/plants-almanac/.git/lint-staged_unstaged.patch` doesn't exist, ignoring... +0ms
  lint-staged:git Done restoring original state! +1ms
Reverting to original state because of errors... [completed]
Cleaning up... [started]
  lint-staged:git Dropping backup stash... +0ms
  lint-staged:git Running git command [ 'stash', 'list' ] +94ms
  lint-staged:git Running git command [ 'stash', 'drop', '--quiet', 'stash@{0}' ] +18ms
  lint-staged:git Done dropping backup stash! +45ms
Cleaning up... [completed]



โœ– npm found some errors. Please fix them and try committing again.

> [email protected] format /Users/lllobera/Documents/lewis/plants-almanac
> concurrently "cd backend && npm run format" "cd frontend && npm run format" "/Users/lllobera/Documents/lewis/plants-almanac/frontend/src/components/index.ts"

[2] /bin/sh: /Users/lllobera/Documents/lewis/plants-almanac/frontend/src/components/index.ts: Permission denied
[2] /Users/lllobera/Documents/lewis/plants-almanac/frontend/src/components/index.ts exited with code 126
[1] 
[1] > @plants-almanac/[email protected] format /Users/lllobera/Documents/lewis/plants-almanac/frontend
[1] > prettier --write --check "!.cache" "!dist" .
[1] 
[0] 
[0] > @plants-almanac/[email protected] format /Users/lllobera/Documents/lewis/plants-almanac/backend
[0] > prettier --write --check "!dist" .
[0] 
[0] Checking formatting...
[1] Checking formatting...
[0] All matched files use Prettier code style!
[0] cd backend && npm run format exited with code 0
[1] src/graphql/types.tsx
[1] Code style issues fixed in the above file(s).
[1] cd frontend && npm run format exited with code 0
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] format: `concurrently "cd backend && npm run format" "cd frontend && npm run format" "/Users/lllobera/Documents/lewis/plants-almanac/frontend/src/components/index.ts"`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] format script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/lllobera/.npm/_logs/2020-05-04T17_07_33_722Z-debug.log



โœ– npm found some errors. Please fix them and try committing again.

> [email protected] lint /Users/lllobera/Documents/lewis/plants-almanac
> concurrently "cd backend && npm run lint" "cd frontend && npm run lint" "/Users/lllobera/Documents/lewis/plants-almanac/frontend/src/components/index.ts"

[2] /bin/sh: /Users/lllobera/Documents/lewis/plants-almanac/frontend/src/components/index.ts: Permission denied
[2] /Users/lllobera/Documents/lewis/plants-almanac/frontend/src/components/index.ts exited with code 126
[1] 
[1] > @plants-almanac/[email protected] lint /Users/lllobera/Documents/lewis/plants-almanac/frontend
[1] > eslint --ext .js,.ts,.tsx .
[1] 
[0] 
[0] > @plants-almanac/[email protected] lint /Users/lllobera/Documents/lewis/plants-almanac/backend
[0] > eslint --ext .js,.ts .
[0] 
[0] cd backend && npm run lint exited with code 0
[1] cd frontend && npm run lint exited with code 0
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] lint: `concurrently "cd backend && npm run lint" "cd frontend && npm run lint" "/Users/lllobera/Documents/lewis/plants-almanac/frontend/src/components/index.ts"`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] lint script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/lllobera/.npm/_logs/2020-05-04T17_07_33_746Z-debug.log
husky > pre-commit hook failed (add --no-verify to bypass)

Did you check the file permissions of the file that's failing to "permission denied"? I wonder if lint-staged is running under another user, maybe.

If both npm command running well separately then I guess the issue is with the path we define in lint-staged.
image

If I understand your configuration correctly, it goes like this:

  1. you commit
  2. git pre-commit hook spawns husky
  3. husky spawns lint-staged
  4. lint-staged spawns the npm command using execa
  5. npm command spawns concurrently
  6. concurrently spawns your "actual" tasks
  7. the actual tasks run a shell script which cd into a folder and then spawn an npm script there
  8. the final npm script runs in the subdirectory based the inner package.json files.

A lot can change in that "call stack", including the user the process belongs to.

I wonder if it would be simpler to configure something like this:

{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged --shell"
    }
  },
  "lint-staged": {
    "backend/**/*.{js,jsx,ts,tsx}": "cd backend && npm run lint",
    "backend/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}": "cd backend && npm run format",
    "frontend/**/*.{js,jsx,ts,tsx}": "cd frontend && npm run lint",
    "frontend/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}": "cd frontend && npm run format"
  }
}

One thing that might be an issue is that since the glob receives files in both the backend and frontend directories, but then the tasks cd into only one of the folders, each will try to run linters to files outside their respective directories.

I found the issue mate. It's because of concurrently. when concurrently runs one script for the file, that file gets locked and another script can't be run with lint-staged.
I replaced
"lint": "concurrently \"cd backend && npm run lint\" \"cd frontend && npm run lint\"",
with
"backend-lint": "npm run lint-backend-fix --prefix backend",

and add lint-backend-fix script in backend/package.json
"lint-backend-fix": "npm run lint && npm run format"

and do the similar with frontend
change lint-staged with only two scripts, like backend-lint and frontend-fix

Both of you are right! ๐ŸŽ‰

@iiroj your proposed solution worked, specially adding the --shell flag:

{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged --shell"
    }
  },
  "lint-staged": {
    "backend/**/*.{js,jsx,ts,tsx}": "cd backend && npm run lint",
    "backend/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}": "cd backend && npm run format",
    "frontend/**/*.{js,jsx,ts,tsx}": "cd frontend && npm run lint",
    "frontend/**/*.{js,jsx,ts,tsx,html,css,json,md,yaml,yml,graphql}": "cd frontend && npm run format"
  }
}

@nirvparekh that was issue indeed, concurrently! It was puzzling at the beginning because if it worked manually I expected to work the same way when running via lint-staged, but didn't know the file being locked during the process, it makes sense now.

Thanks a lot guys!

adding --shell did not worked for me.

Even when splitting the commands to cd into each folder for each command in lint-staged, @nirvparekh?

Was this page helpful?
0 / 5 - 0 ratings