{"record":{"id":"43345eee88f6430b","repo":"evanw/esbuild","slug":"invalid-binding-pattern","errorCode":null,"errorMessage":"Invalid binding pattern","messagePattern":"Invalid binding pattern","errorType":"panic","errorClass":"LexerPanic","httpStatus":null,"severity":"error","filePath":"internal/js_parser/js_parser.go","lineNumber":3304,"sourceCode":"\t\t\t}\n\t\t}\n\n\t\t// Arrow function parsing may be forced if this parenthesized expression\n\t\t// was prefixed by a TypeScript type parameter list such as \"<T,>()\"\n\t\tif isArrowFn || opts.forceArrowFn {\n\t\t\tif commaAfterSpread.Start != 0 {\n\t\t\t\tp.log.AddError(&p.tracker, logger.Range{Loc: commaAfterSpread, Len: 1}, \"Unexpected \\\",\\\" after rest pattern\")\n\t\t\t}\n\t\t\tp.logArrowArgErrors(&arrowArgErrors)\n\t\t\tp.logDeferredArrowArgErrors(&errors)\n\n\t\t\t// Now that we've decided we're an arrow function, report binding pattern\n\t\t\t// conversion errors\n\t\t\tif len(invalidLog.invalidTokens) > 0 {\n\t\t\t\tfor _, token := range invalidLog.invalidTokens {\n\t\t\t\t\tp.log.AddError(&p.tracker, token, \"Invalid binding pattern\")\n\t\t\t\t}\n\t\t\t\tpanic(js_lexer.LexerPanic{})\n\t\t\t}\n\n\t\t\t// Also report syntax features used in bindings\n\t\t\tfor _, entry := range invalidLog.syntaxFeatures {\n\t\t\t\tp.markSyntaxFeature(entry.feature, entry.token)\n\t\t\t}\n\n\t\t\tarrow := p.parseArrowBody(args, fnOrArrowDataParse{\n\t\t\t\tneedsAsyncLoc: loc,\n\t\t\t\tawait:         await,\n\t\t\t})\n\t\t\tarrow.IsAsync = isAsync\n\t\t\tarrow.HasRestArg = spreadRange.Len > 0\n\t\t\tp.popScope()\n\t\t\treturn js_ast.Expr{Loc: loc, Data: arrow}\n\t\t}\n\t}\n","sourceCodeStart":3286,"sourceCodeEnd":3322,"githubUrl":"https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/internal/js_parser/js_parser.go#L3286-L3322","documentation":"Once esbuild decides a parenthesized expression is an arrow function, it validates the parameter bindings. If the collected binding tokens were not legal bindings (invalidLog.invalidTokens is non-empty), it logs 'Invalid binding pattern' for each offending token and aborts.","triggerScenarios":"Arrow parameters that are not valid destructuring/identifier bindings, e.g. '({a-b}) => {}', '(123) => {}', or a stray ':'/operator inside the parameter list.","commonSituations":"Malformed destructuring in arrow params; leftover TypeScript annotation parsed as JS (wrong loader); partial edits leaving stray tokens.","solutions":["Correct the destructuring pattern to use valid property names and commas.","Remove stray tokens/operators from the parameter list.","If the code is TypeScript, ensure the .ts/.tsx loader is used so types parse."],"exampleFix":"// before\nconst f = ({a-b}) => a\n// after\nconst f = ({a, b}) => a","handlingStrategy":"validation","validationCode":"import \"github.com/evanw/esbuild/pkg/api\"\nres := api.Transform(src, api.TransformOptions{Loader: api.LoaderTS})\nfor _, m := range res.Errors {\n  if strings.Contains(m.Text, \"Invalid binding pattern\") {\n    // m.Location is the bad token in the arrow parameter list\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Type-check arrow parameters with tsc; destructuring key names must be valid identifiers.","Use the .ts/.tsx loader for TypeScript so annotations are parsed, not treated as invalid bindings.","Lint destructuring patterns for stray tokens."],"tags":["syntax-error","parser","destructuring","arrow-function"],"backgroundTag":null,"analyzedSha":"f6058f8364fe7ab91ca57a83e02577ed74c9cae4","analyzedAt":"2026-08-09T18:37:22.223Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}