{"record":{"id":"fb373016d52a4975","repo":"usebruno/bruno","slug":"edgegrid-accesstoken-is-required","errorCode":null,"errorMessage":"EdgeGrid: accessToken is required","messagePattern":"EdgeGrid: accessToken is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/bruno-requests/src/auth/edgegrid-helper.js","lineNumber":42,"sourceCode":" * @param {Object} config - EdgeGrid configuration\n * @param {string} config.accessToken\n * @param {string} config.clientToken\n * @param {string} config.clientSecret\n * @param {string} [config.baseURL] - override host the request is signed against\n * @param {string} [config.nonce] - optional nonce override\n * @param {string} [config.timestamp] - optional timestamp override\n * @param {string} [config.headersToSign] - comma-separated header names to sign\n * @param {string|number} [config.maxBodySize=131072]\n * @param {Object} request - axios request config ({ method, url, headers, data })\n * @returns {Promise<string>} Authorization header value\n */\nexport async function signEdgeGridRequest(config, request) {\n  const { accessToken, clientToken, clientSecret, baseURL, headersToSign } = config;\n  const maxBodySize = config.maxBodySize ? parseInt(config.maxBodySize, 10) : MAX_BODY_SIZE_DEFAULT;\n\n  // Validate required fields\n  if (!isStrPresent(accessToken)) {\n    throw new Error('EdgeGrid: accessToken is required');\n  }\n  if (!isStrPresent(clientToken)) {\n    throw new Error('EdgeGrid: clientToken is required');\n  }\n  if (!isStrPresent(clientSecret)) {\n    throw new Error('EdgeGrid: clientSecret is required');\n  }\n\n  // Generate or use provided nonce and timestamp\n  const nonce = isStrPresent(config.nonce) ? config.nonce : makeEdgeGridNonce();\n  const timestamp = isStrPresent(config.timestamp) ? config.timestamp : makeEdgeGridTimestamp();\n\n  // Determine the URL to sign — use baseURL's host/protocol if provided, otherwise the request URL.\n  let urlToSign = request.url;\n  if (isStrPresent(baseURL)) {\n    const requestUrl = new URL(request.url);\n    // A scheme-less baseURL like \"localhost:6000\" mis-parses (\"localhost:\" becomes the protocol\n    // and the host is empty). If there's no \"scheme://\", borrow the request URL's scheme.","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/usebruno/bruno/blob/9bdd81c7bdc57006e5f5ebffb79321a8d979f712/packages/bruno-requests/src/auth/edgegrid-helper.js#L24-L60","documentation":"Thrown by Bruno's Akamai EdgeGrid signing helper when the `accessToken` field is missing or blank in the EdgeGrid config. isStrPresent returns false for null/undefined/empty-string/whitespace, so any of those triggers the throw before signing begins. The EG1-HMAC-SHA256 auth header requires all three credentials.","triggerScenarios":"Configuring a request with EdgeGrid auth where the accessToken field is empty, was never set, or was populated from an empty Bruno environment variable.","commonSituations":"Environment variable name typo (bru.getVar('access_tokn')); credentials stored in a different environment that was not selected; copy-paste left the field blank; secret was cleared.","solutions":["Set config.accessToken to the Akamai API client access token string.","If sourcing from a Bruno variable, verify the variable name and that the environment providing it is active.","Confirm all three EdgeGrid fields (accessToken, clientToken, clientSecret) are populated before sending."],"exampleFix":"// before\nconst config = { clientToken: '...', clientSecret: '...' }; // accessToken missing\n\n// after\nconst config = {\n  accessToken: bru.getVar('EDGEGRID_ACCESS_TOKEN'),\n  clientToken: bru.getVar('EDGEGRID_CLIENT_TOKEN'),\n  clientSecret: bru.getVar('EDGEGRID_CLIENT_SECRET')\n};","handlingStrategy":"validation","validationCode":"function validateEdgeGrid(cfg) {\n  const missing = ['accessToken'].filter((k) => !cfg[k] || !String(cfg[k]).trim());\n  if (missing.length) throw new Error('EdgeGrid missing: ' + missing.join(','));\n}","typeGuard":"const hasAccessToken = (cfg) => typeof cfg?.accessToken === 'string' && cfg.accessToken.trim().length > 0;","tryCatchPattern":"try { await signEdgeGridRequest(config, request); }\ncatch (err) {\n  if (/accessToken is required/.test(err.message)) { config.accessToken = bru.getVar('EDGEGRID_ACCESS_TOKEN'); }\n  else throw err;\n}","preventionTips":["Store all three EdgeGrid credentials as Bruno environment variables.","Validate config completeness in a pre-request script before signing.","Confirm the right environment is active."],"tags":["bruno-requests","auth","edgegrid","akamai","validation"],"backgroundTag":null,"analyzedSha":"9bdd81c7bdc57006e5f5ebffb79321a8d979f712","analyzedAt":"2026-08-13T04:09:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}