{"record":{"id":"10a84da6f3558e43","repo":"can1357/oh-my-pi","slug":"invalid-query-unexpected-token-input-i-in","errorCode":null,"errorMessage":"Invalid query: unexpected token '${input[i]}' in ${query}","messagePattern":"Invalid query: unexpected token '(.+?)' in (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/json-query.ts","lineNumber":60,"sourceCode":"\t\t\tif ((quote === '\"' || quote === \"'\") && raw.endsWith(quote)) {\n\t\t\t\tlet inner = raw.slice(1, -1);\n\t\t\t\tinner = inner.replace(/\\\\([\"'\\\\])/g, \"$1\");\n\t\t\t\ttokens.push(inner);\n\t\t\t} else if (/^\\d+$/.test(raw)) {\n\t\t\t\ttokens.push(Number(raw));\n\t\t\t} else {\n\t\t\t\ttokens.push(raw);\n\t\t\t}\n\t\t\ti = closeIndex + 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst start = i;\n\t\twhile (i < input.length && isIdentChar(input[i])) {\n\t\t\ti++;\n\t\t}\n\t\tif (start === i) {\n\t\t\tthrow new Error(`Invalid query: unexpected token '${input[i]}' in ${query}`);\n\t\t}\n\t\tconst ident = input.slice(start, i);\n\t\ttokens.push(ident);\n\t}\n\n\treturn tokens;\n}\n\n/**\n * Apply a parsed query to a JSON value.\n *\n * @example\n * applyQuery({ foo: { bar: [1, 2, 3] } }, \".foo.bar[0]\") // 1\n */\nexport function applyQuery(data: unknown, query: string): unknown {\n\tconst tokens = parseQuery(query);\n\tlet current: unknown = data;\n\tfor (const token of tokens) {","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/json-query.ts#L42-L78","documentation":"parseQuery throws this when it encounters a character at the current position that cannot start an identifier (only [A-Za-z0-9_-] are allowed) and is not '.' or '['. The tokenizer has no other production, so any stray character like ':', '/', '\"', or '*' outside brackets is rejected with the offending character in the message.","triggerScenarios":"Passing a URL-path form like '/foo/bar' directly to parseQuery instead of going through pathToQuery; queries with slashes, colons, spaces, or quotes outside bracket notation, e.g. '.foo/bar' or '.foo bar'.","commonSituations":"Developers feeding raw path strings ('/data/items') into applyQuery; keys with special characters not wrapped in brackets; copied jq expressions using features (pipes, wildcards, : functions) this subset parser lacks.","solutions":["Wrap non-identifier segments in bracket notation: '.[\"foo/bar\"]' or use pathToQuery('/foo/bar') to build a valid query from a path.","Strip or escape unsupported characters before calling parseQuery.","If the value came from a URL path, call pathToQuery(urlPath) rather than hand-assembling the query."],"exampleFix":"// before\napplyQuery(data, \"/foo/bar\");\n// after\napplyQuery(data, pathToQuery(\"/foo/bar\")); // .foo.bar","handlingStrategy":"validation","validationCode":"if (!/^(\\.?[A-Za-z0-9_-]+)(\\.[A-Za-z0-9_-]+|\\[[^\\]]+\\])*$/.test(query)) throw new Error(`Query has invalid characters: ${query}`);","typeGuard":null,"tryCatchPattern":"try { tokens = parseQuery(query); } catch (e) { if (String(e.message).includes('unexpected token')) { query = pathToQuery(query); tokens = parseQuery(query); } else throw e; }","preventionTips":["Convert URL paths with pathToQuery(), never feed raw paths to parseQuery.","Wrap any key with characters outside [A-Za-z0-9_-] in ['...'] bracket notation.","Remember this parser is a jq subset: no pipes, wildcards, or functions."],"tags":["parser","query-syntax","validation"],"backgroundTag":"query-syntax-error","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}