{"id":"d11a99f3f2b3f82d","repo":"sequelize/sequelize","slug":"failed-to-parse-syntax-of-json-path-parse-error-a","errorCode":null,"errorMessage":"Failed to parse syntax of json path. Parse error at index ${parsed.ref.start.index}:\n${code}\n${' '.repeat(parsed.ref.start.index)}^","messagePattern":"Failed to parse syntax of json path\\. Parse error at index (.+?):\n(.+?)\n(.+?)\\^","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/utils/attribute-syntax.ts","lineNumber":271,"sourceCode":"        >,\n      ]\n    >,\n    castOrModifiers: UselessNode<\n      'castOrModifiers?',\n      [\n        UselessNode<\n          'castOrModifiers',\n          [UselessNode<'(...)+', Array<StringNode<'cast' | 'modifier'>>>]\n        >,\n      ]\n    >,\n  ];\n}\n\nfunction parseJsonPropertyKeyInternal(code: string): ParsedJsonPropertyKey {\n  const parsed = attributeParser.parse(code, false, 'partialJsonPath') as JsonPathAst | ParseError;\n  if (parsed instanceof ParseError) {\n    throw new TypeError(`Failed to parse syntax of json path. Parse error at index ${parsed.ref.start.index}:\n${code}\n${' '.repeat(parsed.ref.start.index)}^`);\n  }\n\n  const [firstKey, jsonPathNodeRaw, castOrModifiersNodeRaw] = parsed.value;\n\n  const pathSegments: Array<string | number> = [parseJsonPathSegment(firstKey)];\n\n  const jsonPathNodes = jsonPathNodeRaw.value[0]?.value[0].value;\n  if (jsonPathNodes) {\n    for (const pathNode of jsonPathNodes) {\n      pathSegments.push(parseJsonPathSegment(pathNode));\n    }\n  }\n\n  const castOrModifierNodes = castOrModifiersNodeRaw.value[0]?.value[0].value;\n  const castsAndModifiers: Array<string | Class<DialectAwareFn>> = [];\n","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/sequelize/sequelize/blob/7e1deec499d5afbb8d1877c2f4d545cead1214ec/packages/core/src/utils/attribute-syntax.ts#L253-L289","documentation":"parseJsonPropertyKeyInternal parses the nested-JSON key syntax (a subset of the attribute syntax used inside JSON columns). When the key violates the partialJsonPath grammar — allowed forms are bare keys, double-quoted keys, and `[index]` access plus optional `::cast`/`:modifier` — Sequelize throws a TypeError with a caret at the failing index.","triggerScenarios":"Querying a JSON column with a malformed nested key such as `'$nested..deep'`, `'data[]'` (empty index), `'json::'` (empty cast), or an unquoted key with characters outside [A-Za-z0-9_-] (use double quotes for those).","commonSituations":"Building JSON path keys from user input without escaping; assuming arbitrary characters are allowed in path segments; mixing the association `$...$` syntax into a JSON-only context; v6 code that relied on looser parsing.","solutions":["Use double quotes around keys with special characters: `'json.\"weird key\".sub'`.","Use `[n]` for numeric index access and single dots between segments.","Validate/escape dynamic path segments before assembling the key; prefer sequelize.jsonPath if available for untrusted paths.","Read the caret line in the error to locate the exact bad index."],"exampleFix":"// before\nModel.findAll({ where: { 'meta.nested..deep': value } }); // bad double dot\n\n// after\nModel.findAll({ where: { 'meta.nested.deep': value } });","handlingStrategy":"validation","validationCode":"const JSON_KEY_RE = /^(?:\"(?:[^\"\\\\]|\\\\.)+\"|[A-Za-z_][\\w-]*|\\d+)(?:\\.(?:\"(?:[^\"\\\\]|\\\\.)+\"|[A-Za-z_][\\w-]*|\\d+)|\\[\\d+\\])*(?:::[A-Za-z_]\\w*|:[A-Za-z_]\\w*)*$/;\nfunction isValidJsonPathKey(key) {\n  return JSON_KEY_RE.test(key);\n}\nif (!isValidJsonPathKey(userKey)) throw new TypeError(`Invalid json path key: ${userKey}`);","typeGuard":"function isValidJsonPathKey(key: string): boolean {\n  return /^(?:\"(?:[^\"\\\\]|\\\\.)+\"|[A-Za-z_][\\w-]*|\\d+)(?:\\.(?:\"(?:[^\"\\\\]|\\\\.)+\"|[A-Za-z_][\\w-]*|\\d+)|\\[\\d+\\])*(?:::[A-Za-z_]\\w*|:[A-Za-z_]\\w*)*$/.test(key);\n}","tryCatchPattern":"try {\n  await Model.findAll({ where: { [jsonKey]: val } });\n} catch (e) {\n  if (/Failed to parse syntax of json path/.test(e.message)) {\n    // rebuild path with quoted segments or use sequelize.jsonPath\n  } else throw e;\n}","preventionTips":["Quote JSON path segments containing special characters.","Use [n] for numeric index access, single dots between keys.","Escape dynamic segments before assembling keys.","Prefer sequelize.jsonPath for untrusted paths."],"tags":["query","attribute-syntax","json","parsing"],"analyzedSha":"7e1deec499d5afbb8d1877c2f4d545cead1214ec","analyzedAt":"2026-08-03T18:58:44.549Z","schemaVersion":2}