{"record":{"id":"d137ba6750de2693","repo":"can1357/oh-my-pi","slug":"fill-is-mutually-exclusive-with-title-and-body","errorCode":null,"errorMessage":"fill is mutually exclusive with title and body","messagePattern":"fill is mutually exclusive with title and body","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/gh-pr-checkout.ts","lineNumber":591,"sourceCode":"\tparams: GithubInput,\n\tsignal: AbortSignal | undefined,\n): Promise<AgentToolResult<GhToolDetails>> {\n\tconst repo = normalizeOptionalString(params.repo);\n\tconst title = normalizeOptionalString(params.title);\n\tconst body = params.body;\n\tconst base = normalizeOptionalString(params.base);\n\tconst head = normalizeOptionalString(params.head);\n\tconst draft = params.draft ?? false;\n\tconst fill = params.fill ?? false;\n\tconst reviewers = normalizePrIdentifierList(params.reviewer);\n\tconst assignees = normalizePrIdentifierList(params.assignee);\n\tconst labels = normalizePrIdentifierList(params.label);\n\n\tif (!fill && !title) {\n\t\tthrow new ToolError(\"title is required unless fill is true\");\n\t}\n\tif (fill && (title || body !== undefined)) {\n\t\tthrow new ToolError(\"fill is mutually exclusive with title and body\");\n\t}\n\n\tconst args = [\"pr\", \"create\"];\n\tappendRepoFlag(args, repo);\n\tif (title) args.push(\"--title\", title);\n\tif (base) args.push(\"--base\", base);\n\tif (head) args.push(\"--head\", head);\n\tif (draft) args.push(\"--draft\");\n\tif (fill) args.push(\"--fill\");\n\tfor (const reviewer of reviewers) args.push(\"--reviewer\", reviewer);\n\tfor (const assignee of assignees) args.push(\"--assignee\", assignee);\n\tfor (const label of labels) args.push(\"--label\", label);\n\n\tlet bodyDir: string | undefined;\n\ttry {\n\t\tif (!fill) {\n\t\t\tif (body !== undefined && body.length > 0) {\n\t\t\t\t// Route through a temp file so multi-KB bodies stay clear of any","sourceCodeStart":573,"sourceCodeEnd":609,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/gh-pr-checkout.ts#L573-L609","documentation":"`fill` is an alternative to explicit title/body, not a combination: fill derives title and body from commit messages, and supplying any of title or body alongside it is ambiguous. The tool rejects the call up front rather than letting gh fail or silently preferring one source.","triggerScenarios":"Calling pr_create with fill=true together with a non-empty title, or fill=true together with a body parameter (body present, even empty string, counts as `body !== undefined`).","commonSituations":"Template/default params that always include a body field, merged with a fill flag from a different code path; users thinking fill only affects the body while supplying a custom title.","solutions":["Remove the title/body parameters and rely solely on fill=true to generate them from commits.","Or remove fill (leave it false) and supply your explicit title/body.","If a framework injects a default empty body, set it to undefined (not \"\") so fill can be used."],"exampleFix":"// before\nop pr_create --fill --title \"Fix login redirect\"\n// after (choose one)\nop pr_create --fill\nop pr_create --title \"Fix login redirect\" --body \"Fixes #42\"","handlingStrategy":"validation","validationCode":"if (params.fill && (params.title || params.body !== undefined)) {\n  throw new Error(\"remove title/body when using fill=true\");\n}","typeGuard":"function fillExclusive(p: { fill?: boolean; title?: string; body?: string }): boolean {\n  return !(p.fill && (p.title !== undefined || p.body !== undefined));\n}","tryCatchPattern":"try {\n  await op.prCreate(params);\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes(\"mutually exclusive\")) {\n    const { fill, title, body, ...rest } = params;\n    await op.prCreate(fill ? rest : { ...rest, title, body }); // pick one mode\n  } else throw err;\n}","preventionTips":["Choose one mode per call: explicit title/body OR fill — never both.","Strip default-injected empty body fields (use undefined, not \"\") when fill is desired.","Keep pr_create wrappers with a single options shape to avoid flag collisions.","Review call sites that merge user params with fill defaults."],"tags":["validation","pr-create","conflicting-options"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}