TypeScriptADK-TS

Troubleshooting

Quick fixes for common artifact errors in ADK-TS — missing service, null returns, GCS auth, and base64 issues.

Most artifact errors fall into one of three categories: the service isn't wired up, a file doesn't exist where you expect it, or a GCS credential or permission is misconfigured. The sections below cover each with a diagnosis and fix.

For general ADK-TS issues (runner errors, session problems, model errors), see the framework troubleshooting guide.

Common issues

IssueCauseFix
"Artifact service is not initialized"No service passed to RunnerCall .withArtifactService() on AgentBuilder, or pass artifactService to Runner directly
loadArtifact returns undefinedArtifact or version doesn't existCheck the filename, scope (user: prefix for user-scoped), and version number
Auto-save (saveInputBlobsAsArtifacts) not workingService not wired, or wrong part typeConfirm artifactService is configured. Message parts must use inlineData, not text
GCS 403 ForbiddenMissing IAM permissionsService account needs roles/storage.objectAdmin on the bucket. Verify ADC or keyFilename
GCS 412 Precondition Failed on saveConcurrent write conflictRetry after a short delay — the GCS service uses ifGenerationMatch: 0 which fails on race conditions
Wrong data after loadLoaded an old versionOmit the version argument to always get the latest, or pass the exact version number
artifact.inlineData is undefinedArtifact was saved as { text }Check artifact.text instead of artifact.inlineData.data
deleteArtifact not found on contextBy design — not exposed on contextsCall it directly on the service instance, not through CallbackContext or ToolContext

Wiring check

If you're seeing "Artifact service is not initialized", verify that the service is actually passed to the runner. The recommended way is through AgentBuilder:

import { AgentBuilder, InMemoryArtifactService } from "@iqai/adk";

const { runner } = await AgentBuilder.create("my_agent")
  .withModel("gemini-2.5-flash")
  .withArtifactService(new InMemoryArtifactService()) // ← required
  .build();

If you're constructing Runner directly, pass it in the options object:

import {
  Runner,
  LlmAgent,
  InMemorySessionService,
  InMemoryArtifactService,
} from "@iqai/adk";

const runner = new Runner({
  appName: "my_app",
  agent: new LlmAgent({ name: "my_agent", model: "gemini-2.5-flash" }),
  sessionService: new InMemorySessionService(),
  artifactService: new InMemoryArtifactService(), // ← required
});

Safe load pattern

loadArtifact returns undefined if the artifact doesn't exist or the version is out of range. Always guard the return value before accessing its fields, and check both text and inlineData since either can be present depending on how the artifact was saved:

const artifact = await ctx.loadArtifact("maybe_exists.txt");

if (!artifact) {
  return { error: "not found" };
}

if (artifact.text) {
  console.log(artifact.text);
} else if (artifact.inlineData) {
  const content = Buffer.from(artifact.inlineData.data, "base64").toString(
    "utf-8",
  );
  console.log(content);
}

GCS auth check

If you're getting 403 Forbidden from GCS, run these commands to verify your credentials are active and the service account has the right permissions on the bucket:

# Confirm active credentials can generate an access token
gcloud auth application-default print-access-token

# Inspect the bucket's IAM policy — look for your service account with roles/storage.objectAdmin
gsutil iam get gs://my-artifacts-bucket

If your service account is missing from the output, grant access:

gsutil iam ch serviceAccount:svc@project.iam.gserviceaccount.com:roles/storage.objectAdmin gs://my-artifacts-bucket

Next steps