Debug Colander Output Bugs: Stray None, Nested Lists, and Empty List Versus Null

Read the full interview experience this question came from →

Quick Overview

A debugging exercise in the Colander validation library, where recorded results contain stray None values, nested lists that should be flat, and an inconsistent mix of empty lists and null. It tests tracing bad output back to the code that produces it, safe list flattening, None handling and choosing one canonical empty value.

Debug Colander Output Bugs: Stray None, Nested Lists, and Empty List Versus Null

Company: Stripe

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Technical Screen

You are given a working copy of **Colander**, an open-source Python library that validates and deserializes data against a declared schema, into which bugs have been planted. Assume the exercise runs the library over a fixed set of inputs, records the results in an output file, and compares that file with the expected results. Three discrepancies are reported: - `None` values appear in the recorded results, and the expected results contain none. - Results that should be flat lists of strings are recorded as nested lists, such as `[s1, [s2, [s3, s4], s5], s6, s7]` where `[s1, s2, s3, s4, s5, s6, s7]` is expected. - Equivalent cases are recorded inconsistently: some record an empty list `[]` and others `null`. Every such case must produce the same value. For each discrepancy, find the code in the library that produces it, fix it there, and add a regression test. ### Constraints and Clarifications - The expected results are the specification: do not edit them, and do not post-process the output file. - Order within a recorded list matters. - Colander represents "no value" with its own marker, `colander.null`, which is distinct from `None`. ### Clarifying Questions - Is `null` in the recorded results Colander's `null` marker, or JSON `null` written by the recorder? - Which representation is canonical for "nothing to report": the empty list or `null`? - How deep can the nesting go, and can `None` appear inside nested lists? - Can a recorded list legitimately contain other falsy values, such as an empty string? ### Part 1 — Stray `None` values Find where a `None` enters a recorded result and remove it at its source. ```hint Walk back from one None Take a single recorded `None` and find the first function whose return value already contains it. Ask what that function should return when it has nothing to contribute. ``` #### What This Part Should Cover - How the `None` was traced to the function that produces it - The fix, and why it belongs there rather than in the code that writes the file - Not discarding legitimate falsy values ### Part 2 — Nested lists Make every result that should be a flat list come out flat, in its original order, however deeply the lists are nested. ```hint Leaves and containers Decide exactly which values count as containers to expand and which are leaves to keep. Try your rule on a string before you trust it. ``` #### What This Part Should Cover - Where the nesting is created and where it is removed - A flattening routine that preserves order and handles any depth - Which types are expanded and which are kept as leaves ### Part 3 — `[]` versus `null` Make equivalent cases record the same value when there is nothing to report. ```hint Two roads to nothing Find the two code paths that produce these cases and pick one representation of "nothing" for both to return. Then check what that representation means to the rest of the library. ``` #### What This Part Should Cover - The two code paths and the chosen canonical value - An empty check that cannot match other values by accident - Side effects of the change on code that already treats `null` specially ### What a Strong Answer Covers - Traces each discrepancy from the recorded output back to the producing code before changing anything - Fixes in the library rather than in the output, with the order of the normalization steps thought through for a list that holds only `None` values - Exact checks: identity tests for `None` and for markers, explicit container types for flattening - Regression tests for each discrepancy and for inputs that combine them - Awareness of what `null` means elsewhere in Colander ### Follow-up Questions - The nesting reaches thousands of levels. Does your flattening still work? - A caller needs to tell "an empty list was supplied" apart from "no value". How do you reconcile that with Part 3? - The same defects come from several methods. Do you fix every producer, or normalize in one place? - What test would stop all three defects from coming back?

Overview: A debugging exercise in the Colander validation library, where recorded results contain stray None values, nested lists that should be flat, and an inconsistent mix of empty lists and null. It tests tracing bad output back to the code that produces it, safe list flattening, None handling and choosing one canonical empty value.

Read the full Stripe Software Engineer interview experience this question came from

|Home/Software Engineering Fundamentals/Stripe
Stripe logo
Stripe
Oct 14, 2026
mediumSoftware EngineerTechnical ScreenSoftware Engineering Fundamentals
0
0

You are given a working copy of Colander, an open-source Python library that validates and deserializes data against a declared schema, into which bugs have been planted. Assume the exercise runs the library over a fixed set of inputs, records the results in an output file, and compares that file with the expected results. Three discrepancies are reported:

  • None values appear in the recorded results, and the expected results contain none.
  • Results that should be flat lists of strings are recorded as nested lists, such as [s1, [s2, [s3, s4], s5], s6, s7] where [s1, s2, s3, s4, s5, s6, s7] is expected.
  • Equivalent cases are recorded inconsistently: some record an empty list [] and others null . Every such case must produce the same value.

For each discrepancy, find the code in the library that produces it, fix it there, and add a regression test.

Constraints and Clarifications

  • The expected results are the specification: do not edit them, and do not post-process the output file.
  • Order within a recorded list matters.
  • Colander represents "no value" with its own marker, colander.null , which is distinct from None .

Clarifying Questions Guidance

  • Is null in the recorded results Colander's null marker, or JSON null written by the recorder?
  • Which representation is canonical for "nothing to report": the empty list or null ?
  • How deep can the nesting go, and can None appear inside nested lists?
  • Can a recorded list legitimately contain other falsy values, such as an empty string?

Part 1 — Stray None values

Find where a None enters a recorded result and remove it at its source.

What This Part Should Cover Guidance

  • How the None was traced to the function that produces it
  • The fix, and why it belongs there rather than in the code that writes the file
  • Not discarding legitimate falsy values

Part 2 — Nested lists

Make every result that should be a flat list come out flat, in its original order, however deeply the lists are nested.

What This Part Should Cover Guidance

  • Where the nesting is created and where it is removed
  • A flattening routine that preserves order and handles any depth
  • Which types are expanded and which are kept as leaves

Part 3 — [] versus null

Make equivalent cases record the same value when there is nothing to report.

What This Part Should Cover Guidance

  • The two code paths and the chosen canonical value
  • An empty check that cannot match other values by accident
  • Side effects of the change on code that already treats null specially

What a Strong Answer Covers Guidance

  • Traces each discrepancy from the recorded output back to the producing code before changing anything
  • Fixes in the library rather than in the output, with the order of the normalization steps thought through for a list that holds only None values
  • Exact checks: identity tests for None and for markers, explicit container types for flattening
  • Regression tests for each discrepancy and for inputs that combine them
  • Awareness of what null means elsewhere in Colander

Follow-up Questions Guidance

  • The nesting reaches thousands of levels. Does your flattening still work?
  • A caller needs to tell "an empty list was supplied" apart from "no value". How do you reconcile that with Part 3?
  • The same defects come from several methods. Do you fix every producer, or normalize in one place?
  • What test would stop all three defects from coming back?