Skip to content

Troubleshooting

Common issues and solutions when working with Configure. For programmatic error handling, see the Error Handling guide.

Authentication

"Invalid phone format"

Phone numbers must include a country code (e.g., +14155551234). Formatting like spaces, dashes, and parentheses is automatically stripped by the SDK and API. The + prefix is auto-prepended if missing.

If using the <configure-phone-input> component, it handles formatting automatically.

"OTP expired"

Verification codes expire after 10 minutes. Request a new one by clicking "Resend" in the <configure-auth> component.

"Rate limited on OTP"

OTP requests are rate-limited to:

  • 1 per 60 seconds per phone number
  • 5 per hour per phone number

Wait for the cooldown before requesting a new code. The <configure-otp-input> component shows a countdown timer automatically.

Token expired

The SDK throws ConfigureError with code AUTH_REQUIRED and suggestedAction: 'reauthenticate'.

JWTs last 30 days. After expiration, re-authenticate:

  • Frontend: The <configure-auth> component handles re-authentication automatically
  • MCP: Run npx configure-mcp login to refresh credentials

Tool Connections

"Tool not connected"

The SDK throws ConfigureError with code TOOL_NOT_CONNECTED and suggestedAction: 'connect_tool'.

The user needs to connect the tool via OAuth before it can be searched. Options:

  • Use tools.connect('gmail') from the SDK to trigger the OAuth flow
  • Render <configure-connection-list> to let the user connect visually
  • Check connection status with profile.get() — the tools field shows which are connected

OAuth popup blocked

Browsers block popups that aren't triggered by a direct user action. Ensure:

  • The tools.connect() call or connection button click happens inside a user-initiated event handler (click, tap)
  • The user's browser allows popups for configure.dev

Connection works but no results

If a tool shows as connected but searches return empty:

  1. Run tools.syncAll() to refresh the tool data
  2. Check that the connected account actually has data (e.g., the Gmail account has emails matching the query)
  3. For Gmail, use specific query operators: from:, subject:, after:, before:

Memory

Memories not saving

Ensure the ingest() call completed successfully. For reliable saves:

  • Check the return value of profile.remember() for errors
  • For batch ingestion via profile.ingest(), await the response — extraction is asynchronous but the API confirms receipt

Wrong agent's memories

When querying memories, filter by agent:

typescript
const memories = await client.profile.getMemories({ agent: 'self' });

Without the agent filter, you get memories from all agents the user has interacted with. Use 'self' to get only your agent's memories.

Batch ingest limits

The ingest() endpoint has these limits:

  • 50 users per batch request
  • 20 conversations per user
  • 500,000 characters maximum total payload

For larger datasets, split into multiple batch calls.


Agent Storage

"Permission denied" on write

User profile writes from agents are restricted to the agent's own namespace: /agents/{your-agent}/. You cannot write to the user's root paths like /identity.json or other agents' namespaces.

To write agent-specific data:

typescript
await client.profile.write(token, userId, '/agents/my-agent/notes/meeting.md', content);

Peer read returns null

The target agent hasn't written any data to the requested path, or the path doesn't exist. Verify:

  1. The target agent name is correct
  2. The target agent has actually written data to that path
  3. Use client.peer.ls(targetAgent, '/') to see what paths exist

Write modes

Storage supports three write modes:

  • overwrite (default) — Replaces the entire node content
  • append — Adds to existing content (useful for logs, memories)
  • merge — Shallow JSON merge for .json nodes (updates only the specified keys)
typescript
// Merge example: only updates 'occupation', keeps other fields
await client.self.write('/soul/identity.json', { occupation: 'engineer' }, { mode: 'merge' });

MCP

"No user token found"

Run the login command and complete phone verification:

bash
npx configure-mcp login

Follow the browser prompts to sign in, then verify your phone number. Credentials are saved to ~/.configure/.

Only self tools visible

Phone verification was skipped during login. User profile tools (memory, search, actions) require a verified phone number. Run npx configure-mcp login again and complete the phone step.

Self-write tools missing

Agent self-write tools (configure_self_write, configure_self_rm, configure_self_remember) are disabled by default. Enable them by setting the environment variable:

json
{
  "mcpServers": {
    "configure": {
      "command": "npx",
      "args": ["-y", "configure-mcp"],
      "env": {
        "CONFIGURE_SELF_WRITE": "true"
      }
    }
  }
}

SDK

"API key missing"

Set the CONFIGURE_API_KEY environment variable or pass it directly to the constructor:

typescript
const client = new ConfigureClient({ apiKey: 'sk_your_secret_key' });

For MCP, credentials are read from ~/.configure/credentials by default. Set CONFIGURE_API_KEY to override.

React Native SSE

React Native doesn't support the EventSource API natively. Pass a polyfill via the eventSourceClass option:

typescript
import EventSource from 'react-native-sse';

const client = new ConfigureClient({
  apiKey: 'sk_xxx',
  eventSourceClass: EventSource,
});

CORS errors

CORS errors occur when using a secret key (sk_) in client-side (browser) code. Secret keys are restricted to server-side use.

Fix: Use a publishable key (pk_) for browser/client-side code, or move the SDK call to your backend:

ContextKey typeExample
Browser / Reactpk_ (publishable)Components, client-side auth
Node.js / serversk_ (secret)API routes, background jobs
MCP serversk_ (secret)Stored in ~/.configure/

Identity and memory infrastructure for AI agents