{"record":{"id":"91a1b044d1208f2d","repo":"tldraw/tldraw","slug":"error-cannot-cherry-pick-docs-changes-from-pr","errorCode":null,"errorMessage":"・ERROR・\nCannot cherry-pick docs changes from PR '${pr.title}' https://github.com/tldraw/tldraw/pulls/${pr}\nThis PR contains changes to the SDK.\n\n${formattedDiff}\n💡 Please cherry-pick this PR manually and remove the sdk changes.\n   Or apply the sdk-hotfix-please PR label and rerun this action to publish the sdk changes if appropriate.","messagePattern":"・ERROR・\nCannot cherry-pick docs changes from PR '(.+?)' https://github\\.com/tldraw/tldraw/pulls/(.+?)\nThis PR contains changes to the SDK\\.\n\n(.+?)\n💡 Please cherry-pick this PR manually and remove the sdk changes\\.\n   Or apply the sdk-hotfix-please PR label and rerun this action to publish the sdk changes if appropriate\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"internal/scripts/trigger-sdk-hotfix.ts","lineNumber":128,"sourceCode":"\t\t\tawait exec('yarn', ['refresh-assets', '--force'])\n\n\t\t\tconst diff = await getAnyPackageDiff(version.format())\n\t\t\tif (diff) {\n\t\t\t\tlet message = kleur.red().bold(`・ERROR・`)\n\t\t\t\tmessage += `\\nCannot cherry-pick docs changes from PR '${kleur.cyan().bold(pr.title)}' https://github.com/tldraw/tldraw/pulls/${pr}`\n\t\t\t\tmessage += '\\nThis PR contains changes to the SDK.\\n\\n'\n\t\t\t\tlet formattedDiff = formatDiff(diff)\n\t\t\t\t// truncate long diffs for discord's sake, it's not that valuable to see the whole thing\n\t\t\t\tif (formattedDiff.length > 1000) {\n\t\t\t\t\tformattedDiff = formattedDiff.slice(0, 1000) + '\\n...\\n'\n\t\t\t\t}\n\t\t\t\tmessage += formattedDiff\n\n\t\t\t\tmessage += '\\n💡 Please cherry-pick this PR manually and remove the sdk changes.'\n\t\t\t\tmessage +=\n\t\t\t\t\t'\\n   Or apply the sdk-hotfix-please PR label and rerun this action to publish the sdk changes if appropriate.'\n\n\t\t\t\tthrow new Error(message)\n\t\t\t}\n\t\t})\n\t} else {\n\t\tawait discord.step('Running sdk tests', async () => {\n\t\t\tawait exec('yarn', ['install'])\n\t\t\tconst packages = await getAllWorkspacePackages()\n\n\t\t\tawait exec('yarn', [\n\t\t\t\t'test',\n\t\t\t\t...packages\n\t\t\t\t\t.filter((p) => !p.packageJson.private)\n\t\t\t\t\t.flatMap(({ name }) => ['--project', name]),\n\t\t\t])\n\t\t})\n\t}\n\n\tawait discord.step('Pushing to release branch', async () => {\n\t\tawait exec('git', ['push', 'origin', `HEAD:${latestReleaseBranch}`])","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/tldraw/tldraw/blob/b31086b44731a7d1d9d46be4163ac8ef7417321d/internal/scripts/trigger-sdk-hotfix.ts#L110-L146","documentation":"Thrown by the SDK hotfix orchestrator when a PR carries the 'docs-hotfix-please' label (intended for docs-only cherry-picks) but the diff check (getAnyPackageDiff) detects changes to SDK package contents. The script refuses to silently ship SDK code changes under a docs-only hotfix and asks for manual intervention or the sdk-hotfix-please label instead. The message includes a truncated diff for context.","triggerScenarios":"A PR labeled docs-hotfix-please touches files under packages/* that change the built output or source of a published package. getAnyPackageDiff against the latest version returns a non-empty diff, triggering the guard.","commonSituations":"A PR was mislabeled (docs-only intent but SDK files changed). A docs change incidentally modified a re-exported type or asset that counts as an SDK diff. The label was applied before the SDK change was added.","solutions":["Cherry-pick the PR manually onto the release branch with the SDK changes removed, keeping only docs files.","If the SDK changes are intentional and should ship, add the 'sdk-hotfix-please' label and rerun the action.","Split the PR into two: one docs-only PR (docs-hotfix-please) and one SDK PR (sdk-hotfix-please).","Inspect the formatted diff in the error message to identify which package files triggered the guard."],"exampleFix":"// before\nif (diff) {\n  // ... build message ...\n  throw new Error(message)\n}\n\n// after: also expose which packages changed for faster triage\nif (diff) {\n  const changedPackages = Object.keys(diff).join(', ')\n  throw new Error(\n    `${message}\\nChanged packages: ${changedPackages}`\n  )\n}","handlingStrategy":"validation","validationCode":"// Before labeling docs-hotfix-please, confirm the PR has no SDK package diff\nimport { getAnyPackageDiff } from './lib/didAnyPackageChange'\n\nconst diff = await getAnyPackageDiff(latestVersion)\nif (diff) {\n  throw new Error(\n    'PR has SDK changes; use sdk-hotfix-please instead of docs-hotfix-please, or split the PR.'\n  )\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Before applying docs-hotfix-please, run getAnyPackageDiff locally to confirm the PR is docs-only.","Split mixed PRs into docs-only and SDK-only PRs so each can take the appropriate label.","Document the label semantics (docs-hotfix-please = strictly docs) in the contributing guide."],"tags":["ci","hotfix","release","sdk","cherry-pick","github"],"backgroundTag":null,"analyzedSha":"b31086b44731a7d1d9d46be4163ac8ef7417321d","analyzedAt":"2026-08-12T17:05:39.947Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}