can1357/oh-my-pi · error · AIError.AwsCredentialsError

web-identity

web-identity

Error message

Unable to read AWS web identity token file: ${String(err)}

What it means

When using IAM roles for service accounts (IRSA) or similar web-identity flows, the library reads the JWT from the file named by AWS_WEB_IDENTITY_TOKEN_FILE. If Bun.file(...).text() throws (missing file, permissions, wrong path), the original error is wrapped in an AwsCredentialsError with kind "web-identity" and attached as cause.

Source

Thrown at packages/ai/src/providers/aws-credentials.ts:766

	);
}

/**
 * Exchange a web-identity token file for role credentials via STS
 * `AssumeRoleWithWebIdentity`. Used by the env chain (`AWS_WEB_IDENTITY_TOKEN_FILE`)
 * and by `role_arn` + `web_identity_token_file` profiles.
 */
async function assumeRoleWithWebIdentity(
	params: { roleArn: string; tokenFile: string; sessionName?: string },
	region: string,
	signal: AbortSignal | undefined,
	fetchImpl: FetchImpl,
): Promise<ResolvedCredentials> {
	let token: string;
	try {
		token = (await Bun.file(params.tokenFile).text()).trim();
	} catch (err) {
		throw new AIError.AwsCredentialsError(
			`Unable to read AWS web identity token file: ${String(err)}`,
			"web-identity",
			{
				cause: err,
			},
		);
	}
	if (!token) {
		throw new AIError.AwsCredentialsError("AWS web identity token file is empty.", "web-identity");
	}
	const body = new URLSearchParams({
		Action: "AssumeRoleWithWebIdentity",
		Version: "2011-06-15",
		RoleArn: params.roleArn,
		RoleSessionName: params.sessionName || `omp-${process.pid}`,
		WebIdentityToken: token,
	});
	const response = await fetchImpl(stsEndpoint(region), {

View on GitHub (pinned to 9690622007)

Solutions

  1. Check the path in AWS_WEB_IDENTITY_TOKEN_FILE exists and is readable: cat "$AWS_WEB_IDENTITY_TOKEN_FILE".
  2. If running outside the intended environment (K8s/EKS), unset AWS_WEB_IDENTITY_TOKEN_FILE and AWS_ROLE_ARN so the resolver falls back to other credential methods.
  3. In containers, mount the service-account token volume or pass the projected token file path correctly.
  4. Fix file permissions or replace an expired/rotated projected token file.

Example fix

// before: env copied into local shell
AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token  # not mounted locally

// after: unset outside the cluster
unset AWS_WEB_IDENTITY_TOKEN_FILE AWS_ROLE_ARN
Defensive patterns

Strategy: validation

Validate before calling

import { isEnoent } from "@oh-my-pi/pi-utils";
async function canReadTokenFile(path) {
  try {
    const t = (await Bun.file(path).text()).trim();
    return t.length > 0;
  } catch (err) {
    return false;
  }
}
// guard env before entering the web-identity path
if (process.env.AWS_WEB_IDENTITY_TOKEN_FILE && !(await canReadTokenFile(process.env.AWS_WEB_IDENTITY_TOKEN_FILE))) {
  throw new Error(`AWS_WEB_IDENTITY_TOKEN_FILE unreadable: ${process.env.AWS_WEB_IDENTITY_TOKEN_FILE}`);
}

Try / catch

try {
  const creds = await resolveAwsCredentials();
} catch (err) {
  if (err instanceof AIError.AwsCredentialsError && err.code === "web-identity" && /Unable to read AWS web identity token file/.test(err.message)) {
    logger.error("Web identity token file unreadable — check mount/permissions or unset AWS_WEB_IDENTITY_TOKEN_FILE", { cause: err });
  } else throw err;
}

Prevention

When it happens

Trigger: assumeRoleWithWebIdentity is invoked because AWS_WEB_IDENTITY_TOKEN_FILE and AWS_ROLE_ARN are set, but the token file path does not exist, is unreadable (permissions), points to a directory, or the filesystem mount (e.g. projected service-account token volume) is unavailable.

Common situations: Running a container locally (docker run) where the /var/run/secrets/eks.amazonaws.com/serviceaccount/token mount was not passed; env var copied into a dev shell without the file existing; Kubernetes pod where the service account token volume is not mounted; typo in AWS_WEB_IDENTITY_TOKEN_FILE path.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/6b4f3c615b6f9393. Report an issue: GitHub.