danielmiessler/Fabric · error · ValueError

Pattern validation failed: {validation_message}

Error message

Pattern validation failed: {validation_message}

What it means

Raised after create_pattern output was written to <pattern>/system.md and validate_pattern(pattern_name) rejected it. validate_pattern checks the created pattern's structure (presence/shape of system.md and possibly fabric.md); failure means the LLM-generated content does not satisfy the expected pattern file layout, or a required companion file is missing. The surrounding handler cleans up the new pattern directory on subprocess errors, so this leaves orphaned/invalid files unless handled.

Source

Thrown at scripts/python_ui/streamlit.py:434

                # Execute pattern
                result = run(
                    cmd, input=content, capture_output=True, text=True, check=True
                )
                structured_content = result.stdout.strip()

                if not structured_content:
                    raise ValueError("No output received from create_pattern")

                # Save the structured content to system.md
                system_file = os.path.join(new_pattern_path, "system.md")
                with open(system_file, "w") as f:
                    f.write(structured_content)

                # Validate the created pattern
                is_valid, validation_message = validate_pattern(pattern_name)
                if not is_valid:
                    raise ValueError(f"Pattern validation failed: {validation_message}")

                logger.info(
                    f"Successfully created pattern '{pattern_name}' with structured content"
                )

            except CalledProcessError as e:
                error_msg = f"Error running create_pattern: {e.stderr}"
                logger.error(error_msg)
                if os.path.exists(new_pattern_path):
                    shutil.rmtree(new_pattern_path)
                return False, error_msg

            except Exception as e:
                error_msg = f"Unexpected error during content structuring: {str(e)}"
                logger.error(error_msg)
                if os.path.exists(new_pattern_path):
                    shutil.rmtree(new_pattern_path)
                return False, error_msg

View on GitHub (pinned to 338b89cfe9)

Solutions

  1. Read validation_message — it names the exact failed check; inspect the generated system.md in the new pattern directory to see what the model actually produced
  2. If the output is wrapped in code fences or preamble, strip them before writing system.md
  3. Retry with a stronger model that follows the create_pattern format, or paste the content into a hand-authored pattern instead
  4. Ensure this error path also removes new_pattern_path like the CalledProcessError handler does, so invalid patterns don't linger and break later listing
  5. Check that validate_pattern and the creation code agree on the pattern directory and required files

Example fix

# before
is_valid, validation_message = validate_pattern(pattern_name)
if not is_valid:
    raise ValueError(f"Pattern validation failed: {validation_message}")

# after
is_valid, validation_message = validate_pattern(pattern_name)
if not is_valid:
    if os.path.exists(new_pattern_path):
        shutil.rmtree(new_pattern_path)  # match the CalledProcessError cleanup
    raise ValueError(f"Pattern validation failed: {validation_message}")
Defensive patterns

Strategy: validation

Validate before calling

# Validate the LLM output BEFORE writing and registering the pattern
REQUIRED_FILES = ("system.md",)

def looks_like_pattern(text: str) -> bool:
    return bool(text) and len(text.strip()) > 20 and not text.strip().startswith("```{")

if not looks_like_pattern(structured_content):
    shutil.rmtree(new_pattern_path, ignore_errors=True)
    return False, "create_pattern output does not look like a pattern system prompt"

Type guard

def is_valid_pattern_dir(path: str) -> bool:
    """Structural check matching validate_pattern's expectations."""
    p = Path(path)
    return p.is_dir() and all((p / f).is_file() and (p / f).stat().st_size > 0 for f in REQUIRED_FILES)

Try / catch

try:
    is_valid, validation_message = validate_pattern(pattern_name)
    if not is_valid:
        if os.path.exists(new_pattern_path):
            shutil.rmtree(new_pattern_path)  # keep cleanup symmetric with CalledProcessError path
        return False, f"Pattern validation failed: {validation_message}"
except OSError as e:
    shutil.rmtree(new_pattern_path, ignore_errors=True)
    return False, f"Could not validate pattern: {e}"

Prevention

When it happens

Trigger: The model returned prose or a preamble instead of the raw pattern content expected in system.md; the validator expects both system.md and fabric.md but only system.md was written; the model wrapped output in markdown fences the validator rejects; pattern name with characters that make validate_pattern look in the wrong directory.

Common situations: Weaker models ignoring the create_pattern output contract, validator rules tightened after patterns were authored, hallucinated front-matter in generated output, case-sensitivity mismatches between the created directory name and what validate_pattern resolves.

Related errors


AI-assisted analysis of danielmiessler/Fabric@338b89cfe9 (2026-08-15). Data as JSON: /api/errors/e310474dca0dacec. Report an issue: GitHub.