{"record":{"id":"818adecbd5cfc976","repo":"Freika/dawarich","slug":"mapchannel-actioncable-consumer-not-available","errorCode":null,"errorMessage":"[MapChannel] ActionCable consumer not available","messagePattern":"\\[MapChannel\\] ActionCable consumer not available","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"app/javascript/maps_maplibre/channels/map_channel.js","lineNumber":24,"sourceCode":" * @param {Object} options - { received, connected, disconnected, enableLiveMode }\n * @returns {Object} Subscriptions object with multiple channels\n */\nexport function createMapChannel(options = {}) {\n  const { enableLiveMode = false, ...callbacks } = options\n  const subscriptions = {\n    family: null,\n    points: null,\n    tracks: null,\n  }\n\n  console.log(\n    \"[MapChannel] Creating channels with enableLiveMode:\",\n    enableLiveMode,\n  )\n\n  // Defensive check - consumer might not be available\n  if (!consumer) {\n    console.warn(\"[MapChannel] ActionCable consumer not available\")\n    return {\n      subscriptions,\n      unsubscribeAll() {},\n    }\n  }\n\n  // Subscribe to family locations if family feature is enabled\n  try {\n    const familyFeaturesElement = document.querySelector(\n      \"[data-family-members-features-value]\",\n    )\n    const features = familyFeaturesElement\n      ? JSON.parse(familyFeaturesElement.dataset.familyMembersFeaturesValue)\n      : {}\n\n    if (features.family) {\n      subscriptions.family = consumer.subscriptions.create(\n        \"FamilyLocationsChannel\",","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/Freika/dawarich/blob/97fad417c5a11b0eb11157890635e015723a2e97/app/javascript/maps_maplibre/channels/map_channel.js#L6-L42","documentation":"Before creating any channel subscription, this module defensively checks that an ActionCable consumer object was passed in. A null/undefined consumer means the cable setup code (importing @rails/actioncable and calling createConsumer) never ran or returned nothing; the function returns an empty subscription set, so family locations, live points, and track updates are all disabled for the session.","triggerScenarios":"createConsumer() moved or renamed in the import chain so undefined is passed into setupMapChannels; the cable bootstrap module failing to load (bundler/tree-shaking issue); an exception during module init swallowing consumer creation; running in an environment where ActionCable is intentionally absent (tests, static previews).","commonSituations":"Refactors of the channels bootstrap module changing its export shape; test harnesses rendering the map without ActionCable; bundler misconfiguration dropping @rails/actioncable from the chunk that calls this module.","solutions":["Trace where the consumer argument originates — it must come from createConsumer() in @rails/actioncable; confirm that import resolves in the bundle","Check the browser console for a failed import of @rails/actioncable before this warning","In tests, inject a minimal fake consumer ({ subscriptions: { create: () => ({ unsubscribe() {} }) } }) or assert the no-subscription path","Ensure the consumer module is imported and executed before map channels are set up"],"exampleFix":"// before\n// consumer may be undefined if bootstrap failed\nsetupMapChannels(consumer, callbacks, enableLiveMode)\n// after\nimport { createConsumer } from \"@rails/actioncable\"\nlet consumer = null\ntry {\n  consumer = createConsumer()\n} catch (e) {\n  console.warn(\"[MapChannel] Could not create ActionCable consumer\", e)\n}\nsetupMapChannels(consumer, callbacks, enableLiveMode)","handlingStrategy":"validation","validationCode":"if (!consumer || typeof consumer.subscriptions?.create !== \"function\") {\n  // Skip realtime entirely — the map still works without live updates\n  return { subscriptions, unsubscribeAll() {} }\n}","typeGuard":"/** @param {unknown} c @returns {boolean} */\nfunction isActionCableConsumer(c) {\n  return Boolean(\n    c &&\n    typeof c === \"object\" &&\n    c.subscriptions &&\n    typeof c.subscriptions.create === \"function\"\n  )\n}","tryCatchPattern":null,"preventionTips":["Create the consumer once in a dedicated bootstrap module and export it so callers cannot receive undefined","Fail loudly (console.error) in development when realtime is requested without a consumer","Hide live-mode UI toggles when the consumer is missing so users are not misled"],"tags":["actioncable","dawarich","realtime","null-guard"],"backgroundTag":"actioncable-consumer-missing","analyzedSha":"97fad417c5a11b0eb11157890635e015723a2e97","analyzedAt":"2026-08-21T17:04:17.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}