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 loginto 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()— thetoolsfield 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:
- Run
tools.syncAll()to refresh the tool data - Check that the connected account actually has data (e.g., the Gmail account has emails matching the query)
- 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:
- The target agent name is correct
- The target agent has actually written data to that path
- Use
client.peer.ls(targetAgent, '/')to see what paths exist
Write modes
Storage supports three write modes:
overwrite(default) — Replaces the entire node contentappend— Adds to existing content (useful for logs, memories)merge— Shallow JSON merge for.jsonnodes (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 loginFollow 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:
| Context | Key type | Example |
|---|---|---|
| Browser / React | pk_ (publishable) | Components, client-side auth |
| Node.js / server | sk_ (secret) | API routes, background jobs |
| MCP server | sk_ (secret) | Stored in ~/.configure/ |