{"record":{"id":"9ed79867e4c3d728","repo":"decolua/9router","slug":"invalid-token-format-token-appears-too-short","errorCode":null,"errorMessage":"Invalid token format. Token appears too short.","messagePattern":"Invalid token format\\. Token appears too short\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/lib/oauth/services/cursor.js","lineNumber":107,"sourceCode":"   * Validate and import token from Cursor IDE\n   * Note: We skip API validation because Cursor API uses complex protobuf format.\n   * Token will be validated when actually used for requests.\n   * @param {string} accessToken - Access token from state.vscdb\n   * @param {string} machineId - Machine ID from state.vscdb\n   */\n  async validateImportToken(accessToken, machineId) {\n    // Basic validation\n    if (!accessToken || typeof accessToken !== \"string\") {\n      throw new Error(\"Access token is required\");\n    }\n\n    if (!machineId || typeof machineId !== \"string\") {\n      throw new Error(\"Machine ID is required\");\n    }\n\n    // Token format validation (Cursor tokens are typically long strings)\n    if (accessToken.length < 50) {\n      throw new Error(\"Invalid token format. Token appears too short.\");\n    }\n\n    // Machine ID format validation (should be UUID-like)\n    const uuidRegex = /^[a-f0-9-]{32,}$/i;\n    if (!uuidRegex.test(machineId.replace(/-/g, \"\"))) {\n      throw new Error(\"Invalid machine ID format. Expected UUID format.\");\n    }\n\n    // Note: We don't validate against API because Cursor uses complex protobuf.\n    // Token will be validated when used for actual requests.\n\n    return {\n      accessToken,\n      machineId,\n      expiresIn: 86400, // Cursor tokens typically last 24 hours\n      authMethod: \"imported\",\n    };\n  }","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/lib/oauth/services/cursor.js#L89-L125","documentation":"CursorService.validateImportToken() (src/lib/oauth/services/cursor.js:107) rejects imported access tokens shorter than 50 characters. Real Cursor access tokens are long opaque strings, so a short value almost certainly means the wrong value (or a truncated copy/paste) was taken from state.vscdb instead of the actual token.","triggerScenarios":"Calling validateImportToken with an accessToken string whose .length < 50 — e.g. pasting a truncated token, passing an API-key-like short value, submitting a placeholder like 'test', or reading the wrong itemTable row.","commonSituations":"Terminal/SQLite browser clipped the long token on copy; the user pasted a user ID or session prefix instead of the token; the sqlite CLI output included quoting that was stripped, leaving a fragment; very old Cursor versions stored a differently shaped token.","solutions":["Re-copy the full token from state.vscdb without truncation — quote it when copying out of the sqlite CLI output.","Verify length before calling: the raw cursorAuth/accessToken value is normally hundreds of characters.","Make sure you selected key='cursorAuth/accessToken' and not another itemTable row.","Log in to Cursor again if the stored token looks stale or malformed, then re-import."],"exampleFix":"// before\nawait cursorService.validateImportToken(userInput.token.trim(), machineId);\n// after\nconst token = String(userInput.token || \"\").trim();\nif (token.length < 50) throw new Error(`Token looks truncated (${token.length} chars); re-copy cursorAuth/accessToken from state.vscdb`);\nawait cursorService.validateImportToken(token, machineId);","handlingStrategy":"validation","validationCode":"const token = String(rawToken || \"\").trim();\nif (token.length < 50) {\n  throw new Error(`Token appears truncated (${token.length} chars). Re-copy cursorAuth/accessToken from state.vscdb in full.`);\n}","typeGuard":"function looksLikeCursorToken(v) {\n  return typeof v === \"string\" && v.length >= 50;\n}","tryCatchPattern":"try {\n  await cursorService.validateImportToken(token, machineId);\n} catch (err) {\n  if (/Token appears too short/.test(err.message)) {\n    console.error(\"Re-copy the full token; terminal output often wraps/truncates long values.\");\n  } else throw err;\n}","preventionTips":["Copy token values from SQLite browsers rather than wrapped terminal output.","Check token length (>= 50) in any import form before submission.","Quote sqlite CLI output when copying to avoid clipping.","Re-login to Cursor if the stored token looks anomalous."],"tags":["validation","cursor","token-format","import"],"backgroundTag":"invalid-token-format","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}