{"record":{"id":"fb8a5cc224dfa3c3","repo":"can1357/oh-my-pi","slug":"interception-message-command-blocked","errorCode":null,"errorMessage":"${interception.message ?? \"Command blocked\"}","messagePattern":"\\$\\{interception\\.message \\?\\? \"Command blocked\"\\}","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"warning","filePath":"packages/coding-agent/src/tools/bash.ts","lineNumber":941,"sourceCode":"\t\t\tif (cd) {\n\t\t\t\tcwd = cd.path;\n\t\t\t\tcommand = cd.rest;\n\t\t\t}\n\t\t}\n\t\tif (asyncRequested && !this.#asyncEnabled) {\n\t\t\tthrow new ToolError(\"Async bash execution is disabled. Enable async.enabled to use async mode.\");\n\t\t}\n\n\t\t// Check both the original command and the cwd-normalized command so\n\t\t// leading `cd ... &&` wrappers do not hide either shell-navigation rules\n\t\t// or the dedicated-tool command that follows the directory change.\n\t\tif (this.session.settings.get(\"bashInterceptor.enabled\")) {\n\t\t\tconst rules = this.session.settings.getBashInterceptorRules();\n\t\t\tconst commandsToCheck = rawCommand === command ? [command] : [rawCommand, command];\n\t\t\tfor (const commandToCheck of commandsToCheck) {\n\t\t\t\tconst interception = checkBashInterception(commandToCheck, ctx?.toolNames ?? [], rules, rawCommand);\n\t\t\t\tif (interception.block) {\n\t\t\t\t\tthrow new ToolError(interception.message ?? \"Command blocked\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst internalUrlOptions: InternalUrlExpansionOptions = {\n\t\t\tskills: this.session.skills ?? [],\n\t\t\tattachments: this.session.getImageAttachments?.() ?? [],\n\t\t\tinternalRouter: InternalUrlRouter.instance(),\n\t\t\tcwd: this.session.cwd,\n\t\t\tsessionFile: this.session.getSessionFile() ?? undefined,\n\t\t\tlocalOptions: {\n\t\t\t\tgetArtifactsDir: this.session.getArtifactsDir,\n\t\t\t\tgetSessionId: this.session.getSessionId,\n\t\t\t},\n\t\t};\n\t\tcommand = await expandInternalUrls(command, { ...internalUrlOptions, ensureLocalParentDirs: true });\n\t\tconst resolvedEnv = env\n\t\t\t? Object.fromEntries(","sourceCodeStart":923,"sourceCodeEnd":959,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/bash.ts#L923-L959","documentation":"When bashInterceptor.enabled is on, every command (both the raw command and the cwd-normalized form after a leading `cd ... &&`) is checked against the configured interception rules before execution. If a rule matches and sets block=true, the tool throws with the rule's message, or the generic 'Command blocked' when no custom message is configured. This is an intentional policy gate, not a malfunction.","triggerScenarios":"Executing a command matched by a blocking interceptor rule — e.g. rules that forbid `rm -rf`, force redirecting package-manager commands to dedicated tools, or block `git push --force` — including commands hidden behind a leading `cd <dir> &&` wrapper.","commonSituations":"Teams shipping shared interceptor policies; prompts that generate `cd subdir && npm run dangerous` and expect the rule not to apply; stale rules from previous projects still enabled in settings.","solutions":["Read the interception message: it usually names the rule and the sanctioned alternative (dedicated tool or allowed command).","Adjust the command to comply (use the dedicated tool the rule suggests, or restructure the command).","If the block is wrong, fix or remove the rule in the bashInterceptor rules settings, or disable bashInterceptor.enabled."],"exampleFix":"// before: blocked by an interceptor rule\nawait bash.execute(id, { command: \"cd /repo && gh pr merge 12 --force\" });\n\n// after: follow the rule's sanctioned path\nawait prTool.execute(id, { action: \"merge\", pr: 12 });","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await bash.execute(id, { command });\n} catch (e) {\n  if (e instanceof ToolError && /blocked/i.test(e.message)) {\n    // read the rule's message and switch to the sanctioned alternative\n    logger.warn(\"command blocked by interceptor\", { msg: e.message });\n  } else throw e;\n}","preventionTips":["Review bashInterceptor rules before automating commands; prefer the dedicated tools they point to.","Avoid `cd X && <cmd>` wrappers — both forms are checked.","Document team interceptor policies so generated commands comply by default."],"tags":["policy","command-blocked","configuration"],"backgroundTag":"command-blocked-by-policy","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}