{"record":{"id":"db9f3c4516bd8b6e","repo":"koala73/worldmonitor","slug":"put-url-failed-http-response-status-body-body-slice-0-300","errorCode":null,"errorMessage":"PUT ${url} failed: HTTP ${response.status}${body ? ` — ${body.slice(0, 300)}` : ''}${response.status === 403 ? ' (need sntryu_ user token with project:write)' : ''}","messagePattern":"PUT (.+?) failed: HTTP (.+?)(.+?)` : ''\\}(.+?)","errorType":"exception","errorClass":null,"httpStatus":403,"severity":"error","filePath":"scripts/sync-sentry-convex-probe-filters.mjs","lineNumber":314,"sourceCode":" * @returns {Promise<Record<string, unknown>>}\n */\nasync function putErrorMessageFilters(token, org, project, filtersText) {\n  const url = `${SENTRY_HOST}/api/0/projects/${org}/${project}/`;\n  const response = await fetch(url, {\n    method: 'PUT',\n    headers: {\n      Authorization: `Bearer ${token}`,\n      Accept: 'application/json',\n      'Content-Type': 'application/json',\n    },\n    body: JSON.stringify({\n      options: { 'filters:error_messages': filtersText },\n    }),\n    signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n  });\n  if (!response.ok) {\n    const body = await response.text();\n    throw new Error(\n      `PUT ${url} failed: HTTP ${response.status}`\n        + (body ? ` — ${body.slice(0, 300)}` : '')\n        + (response.status === 403\n          ? ' (need sntryu_ user token with project:write)'\n          : ''),\n    );\n  }\n  return /** @type {Record<string, unknown>} */ (await response.json());\n}\n\n/**\n * Regenerate the committed internal probe filter list from source.\n *\n * @param {string[]} patterns\n */\nfunction runWrite(patterns) {\n  mkdirSync(dirname(COMMITTED_LIST_PATH), { recursive: true });\n  writeFileSync(COMMITTED_LIST_PATH, formatCommittedFilterList(patterns), 'utf8');","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/koala73/worldmonitor/blob/e586b8b4b80f595aa7ece295eec10d76f2921240/scripts/sync-sentry-convex-probe-filters.mjs#L296-L332","documentation":"putErrorMessageFilters PUTs the merged filters:error_messages value to Sentry project options and throws on any non-ok response, including the status, response body excerpt, and a 403 hint that a sntryu_ user token with project:write is required. It fails fast rather than proceeding to read-back verification after a failed write.","triggerScenarios":"Non-2xx from the PUT of project options: 403 because the token lacks project:write or is not a user token, 401 expired token, 404 wrong org/project, 400 payload rejected by Sentry validation.","commonSituations":"Read-only tokens used for a write operation, SENTRY_API_TOKEN created without the project:write scope, project slug typo, or Sentry rejecting the filter payload.","solutions":["Regenerate the sntryu_ user token ensuring both project:read and project:write scopes and update SENTRY_API_TOKEN.","Confirm SENTRY_ORG/SENTRY_PROJECT point at the intended project.","Inspect the body excerpt in the message for a 400 validation problem with the filter text.","Run with --dry-run first to confirm the merged payload before PUT."],"exampleFix":"// before\nSENTRY_API_TOKEN=sntryu_readonly_token\n// after\n// create user token with scopes: project:read, project:write\nSENTRY_API_TOKEN=sntryu_rw_token","handlingStrategy":"try-catch","validationCode":"const scopes = decodeJwtScopes(token); // or document token scopes at creation\nif (!scopes.includes('project:write')) throw new Error('Token missing project:write');","typeGuard":null,"tryCatchPattern":"try { await putErrorMessageFilters(...); } catch (err) {\n  if (err.message.includes('HTTP 403')) throw new Error('Recreate token with project:read+project:write');\n  throw err;\n}","preventionTips":["Create the user token with both project:read and project:write scopes up front.","Run with --dry-run before any PUT.","Keep write credentials out of read-only CI jobs."],"tags":["http","sentry","api","write-failed"],"backgroundTag":"http-error-response","analyzedSha":"e586b8b4b80f595aa7ece295eec10d76f2921240","analyzedAt":"2026-09-22T01:50:49.965Z","contentChangedAt":"2026-09-22T01:50:49.965Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}