moeru-ai/airi · error · Error

Failed to create token: ${JSON.stringify(response) || 'Unkno

Error message

Failed to create token: ${JSON.stringify(response) || 'Unknown error'}

What it means

Thrown by createToken() when the Aliyun NLS CreateToken API response does not contain a Token object with an Id. The function posts a signed request to the Aliyun REST endpoint and expects { Token: { Id, ExpireTime, UserId } }; any other shape (typically an error body with Code/Message) is serialized into the message for diagnosis. This is the server rejecting the token request.

Source

Thrown at packages/stage-ui/src/libs/providers/providers/aliyun-nls/token.ts:134

export async function createToken(accessKeyId: string, accessKeySecret: string, options?: CreateTokenOptions): Promise<{ token: string, expiresAt: number }> {
  const request = await buildCreateTokenRequest(accessKeyId, accessKeySecret, options)
  const response = await ofetch<{
    NlsRequestId: string
    RequestId: string
    ErrMsg: string
    Token: { ExpireTime: number, Id: string, UserId: string }
  } | {
    RequestId: string
    Message: string
    Code: string
  }>(request.url, { method: 'POST' })

  if ('Token' in response && typeof response.Token === 'object' && 'Id' in response.Token) {
    return { token: response.Token.Id, expiresAt: response.Token.ExpireTime * 1000 }
  }

  throw new Error(`Failed to create token: ${JSON.stringify(response) || 'Unknown error'}`)
}

View on GitHub (pinned to 27111382b4)

Solutions

  1. Read the serialized response in the message — it contains the Aliyun Code (e.g. InvalidAccessKeyId, SignatureDoesNotMatch) and Message.
  2. Verify accessKeyId/accessKeySecret are correct and have NLS permissions; re-paste from the Aliyun console.
  3. Confirm the NLS service is activated for the account/region (default region cn-shanghai).
  4. Ensure system clock is accurate; signature timestamps are sensitive to skew.
Defensive patterns

Strategy: try-catch

Validate before calling

// before createToken, ensure credentials are present and well-formed
if (!accessKeyId || !accessKeySecret) throw new Error('Aliyun credentials required for token creation')
// the server is authoritative; the response shape determines success vs error

Type guard

function isAliyunTokenResponse(r: unknown): r is { Token: { Id: string, ExpireTime: number, UserId: string } } {
  return !!r && typeof r === 'object'
    && 'Token' in (r as object)
    && typeof (r as { Token: unknown }).Token === 'object'
    && 'Id' in (r as { Token: object }).Token
}

Try / catch

try {
  const { token, expiresAt } = await createToken(accessKeyId, accessKeySecret, options)
}
catch (err) {
  if (err instanceof Error && err.message.startsWith('Failed to create token')) {
    // parse the JSON in the message for Aliyun Code; fix credentials/region/permissions
  }
  else throw err
}

Prevention

When it happens

Trigger: ofetch returns a response where 'Token' in response is false, or response.Token is not an object containing Id. The Aliyun API returned an error envelope { RequestId, Message, Code } instead. Causes: invalid accessKeyId/accessKeySecret producing a SignatureDoesNotMatch or InvalidAccessKeyId, no NLS service activated on the account, or quota/permission errors.

Common situations: Wrong AccessKey pair (the signature check fails). Using an account where NLS is not activated. STS/temporary credentials lacking permission. Region mismatch. Clock skew affecting the signature timestamp.

Related errors


AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12). Data as JSON: /api/errors/daf8ba5f816847d3. Report an issue: GitHub.