{"record":{"id":"cd1f535b4db813f0","repo":"google-gemini/gemini-cli","slug":"invalid-syntax-contextinfo-unclosed-injection-s","errorCode":null,"errorMessage":"Invalid syntax${contextInfo}: Unclosed injection starting at index ${startIndex} ('${trigger}'). Ensure braces are balanced. Paths or commands with unbalanced braces are not supported directly.","messagePattern":"Invalid syntax(.+?): Unclosed injection starting at index (.+?) \\('(.+?)'\\)\\. Ensure braces are balanced\\. Paths or commands with unbalanced braces are not supported directly\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/services/prompt-processors/injectionParser.ts","lineNumber":82,"sourceCode":"          injections.push({\n            content: injectionContent.trim(),\n            startIndex,\n            endIndex,\n          });\n\n          index = endIndex;\n          foundEnd = true;\n          break;\n        }\n      }\n      currentIndex++;\n    }\n\n    // Check if the inner loop finished without finding the closing brace.\n    if (!foundEnd) {\n      const contextInfo = contextName ? ` in command '${contextName}'` : '';\n      // Enforce strict parsing (Comment 1) and clarify limitations (Comment 2).\n      throw new Error(\n        `Invalid syntax${contextInfo}: Unclosed injection starting at index ${startIndex} ('${trigger}'). Ensure braces are balanced. Paths or commands with unbalanced braces are not supported directly.`,\n      );\n    }\n  }\n\n  return injections;\n}\n","sourceCodeStart":64,"sourceCodeEnd":90,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/cli/src/services/prompt-processors/injectionParser.ts#L64-L90","documentation":"Thrown by extractInjections() when a trigger sequence (e.g. '!{' for shell or '@{' for includes) is found but brace counting never returns to zero before the end of the string — i.e. the injection is unclosed. The parser does simple brace counting and has no escape mechanism, so unbalanced braces inside the content also trigger it.","triggerScenarios":"A prompt contains '!{echo hi' with no matching '}', or a command/path inside the braces itself contains an unmatched '{' or '}', so braceCount never reaches 0.","commonSituations":"Forgot the closing brace on a shell injection; used a command containing literal braces (awk, find -exec, JSON via echo); pasted a path with a stray brace.","solutions":["Add the missing closing '}' so braces are balanced around the injection.","If the command needs literal braces, wrap the whole command in balanced outer braces (e.g. '!{ sh -c \"...\" }') or avoid braces in the embedded command.","Move brace-heavy logic into a script file invoked without inline braces."],"exampleFix":"// before\nSummarize !{awk '{print $1}' file.txt} output\n// after\nSummarize !{awk \"{print \\$1}\" file.txt} output\n// or simpler: avoid inline braces\nSummarize !{./first-col.sh file.txt} output","handlingStrategy":"validation","validationCode":"function injectionsAreClosed(prompt: string, trigger: string): boolean {\n  let i = 0;\n  while (i < prompt.length) {\n    const start = prompt.indexOf(trigger, i);\n    if (start === -1) break;\n    let j = start + trigger.length, depth = 1;\n    for (; j < prompt.length && depth > 0; j++) {\n      if (prompt[j] === '{') depth++;\n      else if (prompt[j] === '}') depth--;\n    }\n    if (depth !== 0) return false;\n    i = j;\n  }\n  return true;\n}\nif (!injectionsAreClosed(prompt, '!{')) throw new Error('Unbalanced !{...} braces');","typeGuard":"function isBalancedInjection(prompt: string, trigger: string): boolean {\n  return injectionsAreClosed(prompt, trigger);\n}","tryCatchPattern":"try {\n  extractInjections(prompt, '!{', cmdName);\n} catch (e) {\n  if (e instanceof Error && /Unclosed injection/.test(e.message)) {\n    // fix the unbalanced braces, then retry\n  }\n  throw e;\n}","preventionTips":["Always close '!{...}' and '@{...}' with a matching '}'.","Avoid literal unbalanced braces inside injected commands; wrap them in balanced outer braces or use a script.","Lint prompts containing injections before submission."],"tags":["prompt-processor","injection","parsing","shell","syntax"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}