Blog
Using Storytell to Build Storytell
blog category

How Our DevOps Engineer Turns Cryptic System Errors Into Friendly Guidance

By
Louise Maniego
June 10, 2025
How Our DevOps Engineer Turns Cryptic System Errors Into Friendly Guidance

As part of our “How We Use Storytell to Build Storytell” series, Alex Malucelli, our DevOps engineer, shares how he uses Storytell to turn cryptic system errors into clear, actionable guidance. This ensures users always know what’s happening and what they can do next.

Try it yourself

  1. Open Storytell (in the Chrome Extension or directly on the website).
  2. Save the “Humane Error” prompt in your library.
  3. Run it on your trickiest logs or error reports.
  4. Compare the rewritten messages to your current ones.
  5. Update your error messages with user-friendly language.

The stakes: errors that actually help

Bad error messages pass blame, hide details, or read like a stack trace. Good ones explain what happened, reassure users, and offer a clear next step. The difference between “Something went wrong” and “We’re having trouble saving your draft. Nothing was lost. Please retry in a minute” is the difference between panic and progress.

Erika, our CCO and co-founder, shared an article with the crew—“When life gives you lemons, write better error messages”—that inspired this work. It showed how small tweaks in how we talk to users can turn a stressful moment into a supportive one.

Alex noticed that some of our system errors were “impossible to understand by humans.” He used Storytell on Storytell to fix this. In just a few steps, he turned dense system talk into friendly guidance and shipped those updates to production.

Alex’s four-step workflow

Here’s how Alex tackled it:

Step 1 – Save the “Humane Error” prompt

Alex created a reusable prompt in his Storytell Prompt Library. It asks Storytell to:

  • Rewrite each technical error code into a clear, user-friendly sentence
  • Imagine what each error might be about and create an explanation that would make sense to a non-technical user
  • Format the results in a table so it’s easy to review and implement

The exact prompt Alex used:

Prompt
I need you to create user-friendly sentences for each of these Storytell errors, so they can understand what happened. Do your best to try to imagine what the error is about and a version of the error message that would be clear to a non-technical user. Give me the results in a table format.

ErrCloudService                 = ErrThreadsNamespace.NewType("cloud_service_error", errcodes.Internal)
ErrCreateCompletion             = ErrThreadsNamespace.NewType("create_completion", errcodes.Internal)
ErrInsufficientTokens           = ErrThreadsNamespace.NewType("insufficient_tokens", errcodes.ResourceExhausted)
ErrInvalidMessageState          = ErrThreadsNamespace.NewType("invalid_message_state", errcodes.DataLoss)
ErrLLM                          = ErrThreadsNamespace.NewType("llm_error", errcodes.Internal)
ErrMalformedData                = ErrThreadsNamespace.NewType("malformed_data", errcodes.InvalidArgument)
ErrMarshalMessage               = ErrThreadsNamespace.NewType("marshal_message", errcodes.Internal)
ErrReadSnapshot                 = ErrThreadsNamespace.NewType("read_snapshot", errcodes.Internal)
ErrSaveESTx                     = ErrThreadsNamespace.NewType("save_es_tx", errcodes.Internal)
ErrSaveSSTx                     = ErrThreadsNamespace.NewType("save_ss_tx", errcodes.Internal)
ErrStreamResponse               = ErrThreadsNamespace.NewType("stream_response", errcodes.Internal)
ErrUnexpectedResponse           = ErrThreadsNamespace.NewType("unexpected_response", errcodes.Internal)
ErrDepreciated                  = ErrThreadsNamespace.NewType("depreciated", errcodes.FailedPrecondition)
ErrInvalidScope                 = ErrThreadsNamespace.NewType("invalid_scope", errcodes.PermissionDenied)
ErrPerformingSearch             = ErrThreadsNamespace.NewType("performing_search", errcodes.Internal)
ErrUnableToWriteToStringBuilder = ErrThreadsNamespace.NewType("unable_to_write_to_string_builder", errcodes.Internal)
ErrNotFoundOrUnauthorized       = ErrThreadsNamespace.NewType("not_found_or_unauthorized", errcodes.NotFound)
ErrGetThreadIfUserHasAccess     = ErrThreadsNamespace.NewType("get_thread_if_user_has_access", errcodes.PermissionDenied)
ErrBuildingScoped               = ErrThreadsNamespace.NewType("building_scoped", errcodes.Internal)
ErrBeginTx                      = ErrThreadsNamespace.NewType("begin_tx", errcodes.Internal)
ErrPerformingMigration          = ErrThreadsNamespace.NewType("performing_migration", errcodes.Internal)
ErrChatter                      = ErrThreadsNamespace.NewType("chatter", errcodes.Internal)
ErrInvalidMessageCtx            = ErrThreadsNamespace.NewType("invalid_message_ctx", errcodes.Internal)
ErrInvalidAnswerStrategy        = ErrThreadsNamespace.NewType("invalid_answer_strategy", errcodes.Internal)
ErrBuildingPromptOptions        = ErrThreadsNamespace.NewType("building_prompt_options", errcodes.Internal)
ErrDeterminingAnswerStrategy    = ErrThreadsNamespace.NewType("determining_answer_strategy", errcodes.Internal)
ErrPromptBuilderProcessing      = ErrThreadsNamespace.NewType("prompt_builder_processing", errcodes.Internal)
ErrUnableToWriteToPromptBuffer  = ErrThreadsNamespace.NewType("unable_to_write_to_prompt_buffer", errcodes.Internal)
ErrBuildingAssetDisplayNames    = ErrThreadsNamespace.NewType("building_asset_display_names", errcodes.Internal)
ErrTokenOrGrantsNotFound        = ErrThreadsNamespace.NewType("token_or_grants_not_found", errcodes.NotFound)
ErrInvalidThreadParams          = ErrThreadsNamespace.NewType("invalid_params", errcodes.InvalidArgument)
ErrUnmatchedPreviousThreadParam = ErrThreadsNamespace.NewType("unmatched_previous_param", errcodes.InvalidArgument)
ErrUnmatchedThreadPreviousParam = ErrThreadsNamespace.NewType("unmatched_previous_param", errcodes.InvalidArgument)
ErrFailedToCreateThreadShare    = ErrThreadsNamespace.NewType("failed_to_create_thread_share", errcodes.Internal)
ErrDBFailedCommit               = ErrThreadsNamespace.NewType("db_failed_commit", errcodes.Internal)
ErrPopulateAssetMetadata        = ErrThreadsNamespace.NewType("populate_asset_metadata", errcodes.Internal)
ErrBuildScoped                  = ErrThreadsNamespace.NewType("build_scoped", errcodes.Internal)
ErrInvalidSystemMessage         = ErrThreadsNamespace.NewType("invalid_system_message", errcodes.InvalidArgument)
ErrFailedToFindInstruction      = ErrThreadsNamespace.NewType("failed_to_find_system_instruction", errcodes.NotFound)
ErrAttachmentNotFound           = ErrThreadsNamespace.NewType("attachment_not_found", errcodes.NotFound)
ErrStreamedToClient             = ErrThreadsNamespace.NewType("streamed_to_client", errcodes.Internal)
ErrTooManyMessages              = ErrThreadsNamespace.NewType("too_many_messages", errcodes.InvalidArgument)
  

He shared a long list of error codes—like ErrCloudService, ErrCreateCompletion, and ErrInsufficientTokens—and let Storytell do the heavy lifting. In seconds, he had a table of clear, friendly messages ready to drop in.

Step 2 – Gather the raw error output

Alex simulated forced errors—like a connection issue or an internal error—to see how they’d appear for users. He captured the raw error logs directly from these scenarios and fed them into Storytell. This ensured the improved messages addressed real-world issues.

Step 3 – Run the analysis and see how Storytell translates

Alex fed the raw error logs into Storytell. In one click, Storytell returned a table of user-friendly messages—replacing cryptic codes with clear, helpful guidance. Here’s a sample of what it produced:

The difference between an error like “ErrUnexpectedResponse” and a plain-language explanation like “We received an unexpected response from our systems. Please try your request again.” is night and day.

Step 4 – Ship and close the loop

Alex pastes the new copy into the codebase, commits, and ships it. If the same error appears again, he iterates and updates the message. Storytell makes it easy to rerun the prompt and refine wording on the spot.

What makes Alex’s prompt work?

Alex’s prompt follows key principles of great error writing:

  • It says what happened and frames it in a user-friendly way.
  • It’s empathetic and concise—no blame, no fluff.
  • It often suggests a next step, like retrying or refreshing.
  • It doesn’t always reassure users about what’s safe (like drafts or data), and it doesn’t consistently offer an escape hatch if the issue persists.
  • It’s grounded in real-world testing and aligns with the guidance Erika shared: turning stressful moments into opportunities to guide users forward.

While there’s still room to strengthen reassurance and fallback guidance, this approach already makes system errors easier to understand and act on: turning cryptic codes into clear, actionable messages.

Adapting the workflow in your org

  • Identify your worst offenders—search your repo for “error” or check analytics for frequent failures
  • Save Alex’s prompt (or tweak it to fit your brand) in your Prompt Library
  • Capture raw error output with the Chrome extension or paste logs into a thread
  • Run the prompt, review the draft, tweak tone if needed, and ship
  • Track post-release metrics: drop in support tickets, lower bounce rate, happier NPS

Pro tip: Add a severity score so product managers can triage which messages ship first. We found that tackling high-frequency, blocker-level errors delivers the biggest delight per hour invested.

Results we’re aiming for

Alex’s approach aims to make error messages easier to understand and less stressful for users. We’re watching closely as these changes roll out to production, with the goal of helping users stay in flow and always know how to recover from issues.

What’s next in the series

Our Crew keeps finding creative ways to harness Storytell, like using it to turn raw updates into clear changelogs for users or quickly finding relevant Linear tickets to track down bugs. We’ll keep sharing these workflows so you can remix them for your own stack.

Open Storytell and start turning cryptic errors into clear guidance today.

Gallery

Changelogs

Here's what we rolled out this week
No items found.