When the Val Town application first loads, SQLite tables don't exist yet. This causes SQLITE_MISMATCH errors when trying to query non-existent tables, even though the code was catching and handling these errors.
The error was being caught and handled correctly (returning empty arrays/null), but the error was still being logged to the console, making it appear as if something was wrong when it was actually expected behavior.
All database read operations now use this pattern:
try {
const result = await sqlite.execute(query, params);
// Process results
} catch (error: any) {
// Silently handle table not existing yet - this is expected on first load
if (error?.code === 'SQLITE_MISMATCH' || error?.message?.includes('no such table')) {
return []; // or null, depending on function
}
// Only log unexpected errors
console.error('Unexpected error:', error);
return []; // or null
}
-
listThreads()(src/database.ts:178)- Silently returns empty array if tables don't exist
- Only logs unexpected errors
-
getThread()(src/database.ts:125)- Silently returns null if tables don't exist
- Only logs unexpected errors
-
threadExists()(src/database.ts:245)- Already silently returns false if tables don't exist
- No changes needed
First Page Load:
- Database initialization runs:
initializeDatabase() - Creates tables if they don't exist
- Frontend loads and calls
?list=true listThreads()silently returns empty array- UI shows "π No archived threads yet"
- No error messages in console
After First Archive:
- Tables exist and contain data
- All queries work normally
- Thread list displays archived threads
Tables are created on module import:
// main.ts line 9
await initializeDatabase();
This runs before the HTTP handler, ensuring tables exist for subsequent requests.
Silently Handled (Expected):
SQLITE_MISMATCH- Datatype mismatch (often means table doesn't exist)no such table- Table hasn't been created yet
Logged (Unexpected):
- Connection errors
- Permission errors
- Query syntax errors
- Data integrity errors
From Val Town skill documentation:
CRITICAL: When tables don't exist yet, queries will fail with
SQLITE_MISMATCHerrors
- ALWAYS wrap SELECT queries in try-catch blocks and return empty arrays/false for graceful handling
- Tables are created asynchronously on first load, but queries may run before initialization completes
This is a known Val Town SQLite behavior that requires defensive error handling.
To test the fix:
- Fresh deployment - No errors on first page load
- List empty threads - Returns empty array, no console errors
- Archive a thread - Works normally
- List with threads - Shows archived threads
- Get non-existent thread - Returns null gracefully
src/database.ts- All database operationsmain.ts- Database initialization.claude/plugins/custom-skills/valtown-platform/references/platform.md- Platform gotchas.claude/plugins/custom-skills/valtown-platform/references/libraries.md- SQLite best practices