Troubleshooting
No marker genes remain after filtering
Likely cause: thresholds are too strict or marker genes do not overlap
table.var_names.
Inspect: ed.summarize_marker_table(result.markers_df) or
read_markers_dataframe(..., return_diagnostics=True).
Action: relax log2fc_min, pval_cutoff, top_n_genes, ribosomal/mitochondrial
filters, or fix gene identifiers.
Gene names do not overlap
Likely cause: one table uses symbols and the other uses Ensembl IDs.
Inspect: compare set(markers_df["names"]) with set(table.var_names).
Action: map identifiers upstream and rerun marker loading.
posterior_df is None
Likely cause: list-style marker_genes was used, so Phase 1 acts as a row
mask.
Inspect: result.diagnostics["assignment_matrix"].
Action: use a grouped marker table for cell-type-specific priors, or use
assignment_df/phase2_result for this workflow.
All rows are unassigned
Likely cause: all score rows are zero, tied, or below minimum_evidence.
Inspect: row maxima in result.assignment_df and result.assigned_labels.
Action: inspect marker overlap, relax assignment settings, or use a different Phase 2 method.
Too many ties
Likely cause: equal score rows or insufficient marker specificity.
Inspect: result.assignment_df.loc[row].sort_values(ascending=False).
Action: use more specific markers, increase marker counts, or adjust
tie_tolerance carefully.
Phase 1 priors are all zero
Likely cause: no marker signal passed Phase 1 filtering.
Inspect: result.phase1_result.sum(axis=1) and marker overlap.
Action: use filtering_algorithm="quantile" as a fast exploratory shortcut,
relax quantile, or check gene identifiers. The standard Phase 1 workflow
uses permutation filtering.
UCell scores are all zero
Likely cause: too few detected positive markers, constant rows, all-zero rows,
or overly strict expression_threshold.
Inspect: result.diagnostics["phase2"] and UCell marker counts.
Action: lower min_markers, lower expression_threshold, or review marker
roles.
No negative markers are present
Likely cause: marker table has no negative role rows or signed Scanpy
inference was not requested.
Inspect: result.markers_df["marker_role"].value_counts().
Action: provide manual negative markers, use reference phase-specific markers,
or opt into marker_role_inference="scanpy_signed" for Scanpy-style markers.
Reference marker generation returns no markers
Likely cause: reference thresholds are too strict or too few cells remain per group.
Inspect: diagnostics from prepare_markers or read_markers_dataframe.
Action: relax reference thresholds or check group labels and expression layers.
PyDESeq2 raw-count validation fails
Likely cause: selected layer is not raw non-negative integer counts.
Inspect: adata.layers[layer] values and dtype.
Action: provide layer="counts" or another raw-count layer.
Insufficient pseudobulk replicates
Likely cause: sample_col does not contain enough biological replicates for
target/rest comparisons.
Inspect: counts by groupby and sample_col.
Action: use true replicate labels, lower minimums only if scientifically justified, or use a different marker method.
Missing spatial coordinates
Likely cause: visualization or niche detection expected obsm["spatial"].
Inspect: table.obsm.keys() and table.obs.columns.
Action: add coordinates to table.obsm["spatial"] or provide x/y columns
for niche detection.
Candidate pruning incompatibility
Likely cause: prior_weight <= 0, list-style marker_genes, or
refine_group(mode="phase2").
Inspect: workflow parameters.
Action: disable candidate pruning, use grouped markers, or switch refinement to
mode="full".
refine_group finds no eligible locations
Likely cause: parent_threshold is too high or the parent group has no support.
Inspect: parent.priors_df[parent_group] or parent.posterior_df[parent_group].
Action: lower parent_threshold, use the other parent_source, or review
parent markers.
Optional SpatialData dependency missing
Likely cause: SpatialData extras are not installed.
Inspect: import errors mentioning spatialdata.
Action: install easydecon[spatial] or pass an AnnData table directly.
Documentation build import failures
Likely cause: missing core dependencies or environment-specific Numba/Scanpy cache behavior.
Inspect: the first Sphinx traceback.
Action: install python -m pip install -e ".[docs]"; if Scanpy import fails in
the local environment, run with NUMBA_DISABLE_JIT=1.
High runtime for permutation Phase 1
Likely cause: large num_permutations, subsample_size, or many marker
groups.
Inspect: Phase 1 progress bars and parameter values.
Action: use filtering_algorithm="quantile" for iteration when you need a
fast exploratory shortcut, then return to permutation filtering for standard
analyses.
Memory concerns
Likely cause: large spatial matrices, dense conversions in selected workflows, or high parallelism.
Inspect: matrix sparsity, selected Phase 2 method, and config.n_jobs.
Action: reduce n_jobs, use smaller marker sets, preserve sparse inputs, and
avoid unnecessary full-data copies.