{"record":{"id":"3e9ebeedd451d814","repo":"can1357/oh-my-pi","slug":"invalid-query-empty-in-query","errorCode":null,"errorMessage":"Invalid query: empty [] in ${query}","messagePattern":"Invalid query: empty \\[\\] in (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/json-query.ts","lineNumber":39,"sourceCode":"\tconst tokens: Array<string | number> = [];\n\tlet i = 0;\n\n\tconst isIdentChar = (ch: string) => /[A-Za-z0-9_-]/.test(ch);\n\n\twhile (i < input.length) {\n\t\tconst ch = input[i];\n\t\tif (ch === \".\") {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \"[\") {\n\t\t\tconst closeIndex = input.indexOf(\"]\", i + 1);\n\t\t\tif (closeIndex === -1) {\n\t\t\t\tthrow new Error(`Invalid query: missing ] in ${query}`);\n\t\t\t}\n\t\t\tconst raw = input.slice(i + 1, closeIndex).trim();\n\t\t\tif (!raw) {\n\t\t\t\tthrow new Error(`Invalid query: empty [] in ${query}`);\n\t\t\t}\n\t\t\tconst quote = raw[0];\n\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++;","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/json-query.ts#L21-L57","documentation":"parseQuery throws this when a bracket segment contains nothing (or only whitespace) between '[' and ']'. Bracket notation must carry either a numeric index, a quoted key, or a bare token; '[]' and '[ ]' are rejected as meaningless.","triggerScenarios":"Calling parseQuery/applyQuery with '.foo[]', '.a[ ]', or consecutive brackets like '.foo[][0]'. Also produced by pathToQuery if a path segment somehow collapses to empty after filtering — though normally pathToQuery skips empty segments.","commonSituations":"Dynamically built queries where a segment variable was empty ('.' + name + '[]' with name=''); template strings whose interpolation produced nothing; users copying jq's '[]' iterate-all syntax which this mini-parser does not support.","solutions":["Put an explicit key or numeric index inside the brackets: '.foo[0]' or '.foo[\"key\"]'.","If you intended jq-style array iteration, implement a loop over the array in code instead — applyQuery only selects single elements.","Guard dynamic construction: skip empty segments before appending brackets."],"exampleFix":"// before\nconst q = `.items[${idx}]`; // idx === ''\n// after\nconst q = idx !== '' ? `.items[${idx}]` : `.items`;","handlingStrategy":"validation","validationCode":"if (/\\[\\s*\\]/.test(query)) throw new Error(`Empty [] in query: ${query}`);","typeGuard":null,"tryCatchPattern":"try { tokens = parseQuery(query); } catch (e) { if (String(e.message).includes('empty []')) { /* skip segment or prompt for an index */ } else throw e; }","preventionTips":["Never use jq's '[]' iteration syntax — this parser selects single elements only.","Check that interpolated index/key variables are non-empty before building the query.","Prefer explicit indices from array length checks (idx < arr.length)."],"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"}