Skip to content

Fix runtime crashes from non-array API responses, 405 on play endpoint, and WGSL reserved keyword#515

Draft
Copilot wants to merge 3 commits intomainfrom
copilot/fix-runtime-errors-after-pr-514
Draft

Fix runtime crashes from non-array API responses, 405 on play endpoint, and WGSL reserved keyword#515
Copilot wants to merge 3 commits intomainfrom
copilot/fix-runtime-errors-after-pr-514

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 12, 2026

Several runtime errors introduced or left unaddressed after PR #514 cause app crashes and broken shader rendering. This PR fixes them with targeted, defensive changes.

API response type guards

API endpoints occasionally return non-array payloads (wrapped objects, error responses, etc.). Calling .map() or .filter() directly on these crashes the app instead of falling back gracefully.

Added Array.isArray() guards that throw a descriptive TypeError when the response isn't an array, letting existing catch blocks trigger the local fallbacks:

// shaderApi.ts & contentLoader.ts & App.tsx
const data = await response.json();
if (!Array.isArray(data)) {
  throw new TypeError(`API response is not an array, received: ${typeof data}`);
}

405 on play tracking endpoint

The play-count fetch was sending POST but the server only accepts GET:

// Before
fetch(`${SHADER_WGSL_URL}/${shaderEntry.id}/play`, { method: 'POST' })
// After
fetch(`${SHADER_WGSL_URL}/${shaderEntry.id}/play`, { method: 'GET' })

WGSL reserved keyword in gen-crystalline-chrono-dyson

mod is a reserved keyword in WGSL, causing a GPUValidationError at shader compilation and cascading [Invalid CommandBuffer] failures. Renamed the custom helper to fmod.

Missing shader defaults

Added SHADER_DEFAULTS entries for digital-haze and gen-crystalline-chrono-dyson (tuned to the shaders' param semantics: Panel Density, Quasar Glow, Flux Speed, Swarm Count) so they don't silently fall back to generic 0.5 values.

Original prompt

Fix persistent runtime errors after the merged PR #514:

  1. TypeError in image manifest loading: data.map is not a function (App.tsx:409) - API response may not be an array
  2. TypeError in shader list loading: data.filter is not a function (shaderApi.ts:359) - same issue
  3. 405 Method Not Allowed on shader play endpoint - change POST to GET
  4. WGSL compilation error: 'mod' is a reserved keyword in gen-crystalline-chrono-dyson shader - rename function
  5. Missing shader defaults for "digital-haze" and "gen-crystalline-chrono-dyson" - add hardcoded defaults
  6. Handle API responses that aren't arrays gracefully

Add proper error handling to prevent crashes when API returns unexpected data types, fix the HTTP method for play tracking, rename reserved WGSL keywords, and add missing shader parameter defaults.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: are any of these errors that need attention:

Backend API failed, trying local manifest... TypeError: (intermediate value).map is not a function
at App.tsx:409:37
overrideMethod @ installHook.js:1Understand this warning

[ShaderApi] API failed, falling back to local shader definitions: TypeError: B.filter is not a function
at Qk.getShaderList (shaderApi.ts:359:35)
at async App.tsx:496:23 installHook.js:1Understand this warning

Failed to load resource: the server responded with a status of 405 (Method Not Allowed) storage.noahcohn.com/api/shaders/liquid-displacement/play:1 

[getShaderDefaults] No defaults found for "digital-haze" (tried: digital-haze, digital-haze, digital-haze.wgsl, digital_haze, digital-haze, digital-haze)

[getShaderDefaults] No defaults found for "gen-crystalline-chrono-dyson" (tried: gen-crystalline-chrono-dyson, gen-crystalline-chrono-dyson, gen-crystalline-chrono-dyson.wgsl, gen_crystalline_chrono_dyson, gen-crystalline-chrono-dyson, gen-crystalline-chrono-dyson)

installHook.js:1 [WebGPU] Uncaptured error:
GPUValidationError
message
:
"Error while parsing WGSL: :29:4 error: 'mod' is a reserved keyword\nfn mod(x: f32, y: f32) -> f32 {\n ^^^\n\n\n - While calling [Device "PixelocityDevice"].CreateShaderModule([ShaderModuleDescriptor ""gen-crystalline-chrono-dyson""]).\n"
[[Prototype]]
:
GPUValidationError

index.html:1 Error while parsing WGSL: :29:4 error: 'mod' is a reserved keyword
fn mod(x: f32, y: f32) -> f32 {
^^^

  • While calling [Device "PixelocityDevice"].CreateShaderModule([ShaderModuleDescriptor ""gen-crystalline-chrono-dyson""]).
    installHook.js:1 [WebGPU] Shader 'gen-crystalline-chrono-dyson' compilation warnings:
    Array(1)

[Invalid CommandBuffer from CommandEncoder "frame"] is invalid due to a previous error.

  • While calling [Queue].Submit([[Invalid CommandBuffer from CommandEncoder "frame"]])

Assistant: Yes, several of these errors need immediate attention as they indicate runtime failures that could crash the app or prevent features from working. Here's a breakdown:

Critical Errors (Break Functionality):

  1. API Response Handling Failures: The TypeError "map is not a function" in App.tsx:409 and "filter is not a function" in shaderApi.ts:359 occur when the backend API returns non-array data (likely null or an object). This causes the app to fail loading image manifests and shader lists, falling back to empty/incomplete data.

  2. WGSL Compilation Error: The "mod" keyword is reserved in WGSL, causing gen-crystalline-chrono-dyson shader to fail compilation. This breaks shader rendering for that effect.

  3. HTTP Method Mismatch: The 405 error on the shader play endpoint suggests it's trying POST but the server expects GET. This prevents play event tracking from working.

Important but Non-Critical:
4. Missing Shader Defaults: No hardcoded defaults exist for "digital-haze" and "gen-crystalline-chrono-dyson", causing parameters to default to generic 0.5 values instead of tuned settings.

  1. Command Buffer Invalid: This cascades from the WGSL error, causing WebGPU rendering failures.

Recommendations:

  • Add defensive checks in API response handlers to ensure data is an array before calling .map() or .filter().
  • Change the play event fetch from POST to GET.
  • Rename the mod function in the WGSL shader to avoid the reserved keyword.
  • Add missing shader defaults to SHADER_DEFAULTS in App.tsx.
  • Improve error handling to log issues without crashing the app.

These issues likely persist because the merged PR didn't fully address API robustness or shader validation. Would you like me to create a pull request to fix these?

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Fix persistent runtime errors after merged PR #514 Fix runtime crashes from non-array API responses, 405 on play endpoint, and WGSL reserved keyword Apr 12, 2026
Copilot AI requested a review from ford442 April 12, 2026 02:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants