Skip to content

Federal AGI drops a Schedule C loss when the same person has Schedule C profit in the other SSTB category #9989

Closed

Description

@PavelMakarchuk

Summary

When one person has a loss in self_employment_income (non-SSTB Schedule C) and a profit in sstb_self_employment_income (SSTB Schedule C), or the reverse, the loss never reaches AGI. irs_gross_income counts each category's profit on its own, but loss_ald deducts only the negative part of the person's net total_self_employment_income. A $5,000 loss next to a $5,000 profit therefore gives AGI of $5,000 and loss_ald of $0. Per the 2024 Schedule C, Schedule 1 and Form 1040, both Schedule C results go on Schedule 1 line 3, so AGI is $0.

Both pieces came from #7944, which added sstb_self_employment_income to gov.irs.gross_income.sources and switched loss_ald to total_self_employment_income. Self-employment tax is not affected: it already nets the two categories (case C below).

Reproduction

policyengine-us main at 07227ea, single filer, age 40, TX, 2024. Only the inputs listed are set.

Case self_employment_income sstb_self_employment_income employment_income irs_gross_income loss_ald self_employment_tax_ald adjusted_gross_income income_tax
A -5,000 5,000 0 5,000 0 0 5,000 0
B 5,000 -5,000 0 5,000 0 0 5,000 0
C -5,000 8,000 0 8,000 0 211.94 7,788.06 -213.29
D -5,000 5,000 50,000 55,000 0 0 55,000 4,616
E (control) 0 0 50,000 50,000 0 0 50,000 4,016

In case C, self_employment_tax_ald of $211.94 is half the SE tax on the net $3,000 (3,000 × 0.9235 × 0.153 / 2), so the SE tax path nets the categories while the AGI path does not. Case D shows the effect on tax: the same AGI under the forms (see below) but $600 more income tax than control E.

from policyengine_us import Simulation

sim = Simulation(situation={
    "people": {"p": {"age": {2024: 40},
                     "self_employment_income": {2024: -5_000},
                     "sstb_self_employment_income": {2024: 5_000}}},
    "tax_units": {"tu": {"members": ["p"]}},
    "households": {"h": {"members": ["p"], "state_code": {2024: "TX"}}},
})
for v in ["total_self_employment_income", "irs_gross_income",
          "loss_ald", "adjusted_gross_income"]:
    print(v, sim.calculate(v, 2024)[0])
# total_self_employment_income 0.0
# irs_gross_income 5000.0
# loss_ald 0.0
# adjusted_gross_income 5000.0

Mechanism

irs_gross_income.py L17–L19 floors each source at zero, and sources.yaml L5–L6 lists the two Schedule C categories as separate sources:

        for source in sources:
            # Add positive values only - losses are deducted later.
            total += not_dependent * max_(0, add(person, period, [source]))
    - self_employment_income
    - sstb_self_employment_income

loss_ald.py L34–L35 takes the loss from the net of both categories (total_self_employment_income adds = ["self_employment_income", "sstb_self_employment_income"]):

        indiv_se_income = max_(0, person("total_self_employment_income", period))
        indiv_se_loss = max_(0, -person("total_self_employment_income", period))

With -5,000 and +5,000, gross income takes max_(0, -5,000) + max_(0, 5,000) = 5,000, while loss_ald takes max_(0, -(−5,000 + 5,000)) = 0. The $5,000 loss is dropped. The other business sources (farm, rental, farm rent, estate, partnership/S-corp, Form 4797 other net gain) take profit and loss from the same quantity in both places, so only the Schedule C pair is out of step.

dependent_taxable_ss_magi already nets the two categories: both are in its BUSINESS_LOSS_SOURCES, so when loss_ald is an allowed deduction it adds each one without a floor.

What the 2024 forms say

Schedule C (Form 1040) 2024, page 1, lines 31–32
31 Net profit or (loss). Subtract line 30 from line 29.
• If a profit, enter on both Schedule 1 (Form 1040), line 3, and on Schedule SE, line 2. (If you checked the box on line 1, see instructions.) Estates and trusts, enter on Form 1041, line 3.
• If a loss, you must go to line 32.
32 If you have a loss, check the box that describes your investment in this activity. See instructions.
• If you checked 32a, enter the loss on both Schedule 1 (Form 1040), line 3, and on Schedule SE, line 2. […]

Instructions for Schedule C (Form 1040) 2024, page C-3, "Line A"
If you owned more than one business, complete a separate Schedule C for each business.

Instructions for Schedule C (Form 1040) 2024, page C-15, "Line 31" › "Reporting your net profit or loss"
Individuals. Enter your net profit or loss on line 31 and include it on Schedule 1 (Form 1040), line 3. Also, include your net profit or loss on Schedule SE, line 2.

Schedule 1 (Form 1040) 2024, page 1, Part I — Additional Income
3 Business income or (loss). Attach Schedule C
10 Combine lines 1 through 7 and 9. This is your additional income. Enter here and on Form 1040, 1040-SR, or 1040-NR, line 8

Form 1040 (2024), page 1
8 Additional income from Schedule 1, line 10
9 Add lines 1z, 2b, 3b, 4b, 5b, 6b, 7, and 8. This is your total income
10 Adjustments to income from Schedule 1, line 26
11 Subtract line 10 from line 9. This is your adjusted gross income

26 U.S.C. § 62(a)(1) (LII)
For purposes of this subtitle, the term "adjusted gross income" means, in the case of an individual, gross income minus the following deductions: (1) Trade and business deductions The deductions allowed by this chapter (other than by part VII of this subchapter) which are attributable to a trade or business carried on by the taxpayer, if such trade or business does not consist of the performance of services by the taxpayer as an employee.

For context only (this governs SE tax, which PE already nets correctly, not AGI):

Instructions for Schedule SE (Form 1040) 2024, pages SE-2–SE-3, "More Than One Business"
If you had two or more businesses subject to SE tax, your net earnings from self-employment are the combined net earnings from all of your businesses. If you had a loss in one business, it reduces the income from another. Figure the combined SE tax on one Schedule SE.

The SSTB/non-SSTB split is a § 199A classification; total_self_employment_income documents both variables as "Schedule C income". A person with amounts in both categories has two businesses and so two Schedules C (Line A), and both line 31 results go to Schedule 1 line 3. PE applies no at-risk (§ 465) or passive-activity (§ 469) limit to self_employment_income or sstb_self_employment_income, so the repro corresponds to a loss that is fully at risk (box 32a) and not passive.

Expected values (from the forms above)

  • Case A: Schedule C (non-SSTB) line 31 = (5,000); Schedule C (SSTB) line 31 = 5,000. Schedule 1 line 3 = 0, line 10 = 0. Schedule SE line 2 = 0, so no SE tax and no SE-tax adjustment. Form 1040 line 8 = 0, line 9 = 0, line 11 AGI = 0.
  • Case B: the same with the signs swapped. AGI = 0.
  • Case D: case A plus $50,000 wages on line 1z. Schedule 1 line 3 = 0, so Form 1040 line 9 = 50,000, line 10 = 0, line 11 AGI = 50,000 — the same AGI as control E.

Proposed fix

Deduct each Schedule C category's loss on its own in loss_ald, which matches how irs_gross_income counts each category's profit on its own:

-        indiv_se_income = max_(0, person("total_self_employment_income", period))
-        indiv_se_loss = max_(0, -person("total_self_employment_income", period))
+        # irs_gross_income counts each Schedule C category's profit on its
+        # own, so each category's loss is deducted on its own here.
+        non_sstb_se = person("self_employment_income", period)
+        sstb_se = person("sstb_self_employment_income", period)
+        indiv_se_income = max_(0, non_sstb_se) + max_(0, sstb_se)
+        indiv_se_loss = max_(0, -non_sstb_se) + max_(0, -sstb_se)

The § 461(l) cap is unaffected for the same net amount: with business profit I, loss L and threshold T, the allowed net is I − min(L, I + T) = max(I − L, −T) whether the two categories are netted first or not.

Open PRs #9890 and #9762 move this block into a new limited_business_loss.py with the same total_self_employment_income lines. Whichever merges first, the same change belongs in that file.

An alternative is to replace the two entries in gov.irs.gross_income.sources with total_self_employment_income. That changes the zero floor for about ten other consumers of the list (medicaid_irs_gross_income, dependent_gross_income, taxable_ss_magi, taxable_uc_agi, student_loan_interest_ald_magi, capped_qualified_tuition_expenses_ald, the CRFB and tax-exempt reforms) and needs BUSINESS_LOSS_SOURCES in dependent_taxable_ss_magi.py updated, so the loss_ald change is the smaller fix.

Tests

For tests/policy/baseline/gov/irs/income/taxable_income/adjusted_gross_income/above_the_line_deductions/self_employment_income.yaml. Expected values come from the form arithmetic above.

- name: Non-SSTB Schedule C loss offsets SSTB Schedule C profit in AGI
  period: 2024
  input:
    self_employment_income: -5_000
    sstb_self_employment_income: 5_000
  output:
    adjusted_gross_income: 0

- name: SSTB Schedule C loss offsets non-SSTB Schedule C profit in AGI
  period: 2024
  input:
    self_employment_income: 5_000
    sstb_self_employment_income: -5_000
  output:
    adjusted_gross_income: 0

- name: Offsetting Schedule C results leave AGI equal to wages
  period: 2024
  input:
    employment_income: 50_000
    self_employment_income: -5_000
    sstb_self_employment_income: 5_000
  output:
    adjusted_gross_income: 50_000

Local check against main at 07227ea: all three tests fail without the fix and pass with it.

Related

Activity

  1. added a commit that references this issue on Oct 13, 2026
    8955fc1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions