91³Ô¹ÏÍø

Watch CBS News

Melissa Hortman, Minnesota lawmaker killed in targeted shootings, is remembered as devoted public servant

Minnesota state Rep. Melissa Hortman and her husband Mark are being mourned after being fatally shot at their home overnight Saturday, while state Sen. John Hoffman and his wife were wounded in a shooting at their home. Gov. Tim Walz called the attacks  "politically motivated." 

The Hortmans were shot and killed at their home in Brooklyn Park, and the Hoffmans were shot at their home in Champlin. 

According to the medical examiner, Hortman, 55, died of multiple gunshot wounds at her home. Her husband, Mark, died of multiple gunshot wounds at North Memorial Health Hospital in Robbinsdale.

inx-hortman-capitol-memorial-061525-1.jpg
A memorial for Minnesota state Rep. Melissa Hortman and her husband is set up outside the Capitol in St. Paul on June 15, 2025. WCCO

Law enforcement officials have identified the suspect as 57-year-old Vance Luther Boelter of Minnesota. He was taken into custody after a manhunt Sunday night. 

Walz ordered flags at half-staff at all state buildings in Minnesota in honor and remembrance of Hortman. 

"Today Minnesota lost a great leader. A formidable public servant and a fixture of the state Capitol, Melissa Hortman woke up every day determined to make our state a better place," Walz said. "She served the people of Minnesota with grace, compassion, and tirelessness. Minnesota's thoughts are with her loved ones."

Who was Melissa Hortman?

Hortman, 55, represented Minnesota House District 34B as a member of the Democratic Party. Her district covers Brooklyn Park, Coon Rapids and Champlin. 

Until Hortman was killed, the Minnesota state House was evenly divided 67-67. In the state Senate, Democrats hold a one-seat majority.

Hortman also served as the Speaker Emerita of the Minnesota House. 

Hortman was elected to the Minnesota Legislature in 2004 and was in her 11th term. She and her husband leave behind two children. 

Last month, Hortman talked to WCCO in the lead-up to the potential special session where lawmakers finished up the budget. 

snapshot-2022-11-13t114246-992.jpg
Melissa Hortman CBS

"Melissa Hortman represented the best of Minnesota," DFL party chair Richard Carlbom said in a statement. "She was a tireless, devoted public servant who deeply loved our state and devoted her life to making it a better place. The warmth and kindness she showed to her family and friends were matched only by her fierce commitment to improving the lives of those she had never even met."

"Hortman was someone who served the people of Minnesota with grace, compassion, humor, and a sense of service," Walz said. "She was a formidable public servant. A fixture and a giant in Minnesota."

Who is John Hoffman?

Hoffman, 60, represents Minnesota Senate District 34, which covers a swath of the northwest Twin Cities suburbs, including Rogers and Champlin. He was also a member of the Democratic Party. 

Hoffman was first elected to serve in 2012, and was reelected three times after.

He served as chair of the Human Services Committee, and also served on committees for energy, environment and health and human services.

He was born in 1965. He has one child. 

36hoffman.jpg
Minnesota state Sen. John Hoffman Minnesota State Senate

Walz denounces political violence

The governor released this statement late Saturday morning regarding the shootings:

"Today Minnesota lost a great leader, and I lost a friend. A formidable public servant and a fixture of the state Capitol, Melissa Hortman woke up every day determined to make our state a better place. She served the people of Minnesota with grace, compassion, and tirelessness.

Minnesota's thoughts are with her loved ones, and my prayers are with Senator John Hoffman and his wife Yvette, who were shot and wounded and are being treated. We are not a country that settles our differences at gunpoint. We have demonstrated again and again in our state that it is possible to peacefully disagree, that our state is strengthened by civil public debate.

We must stand united against all forms of violence – and I call on everyone to join me in that commitment. To the responding officers, thank you for your bravery and your swift action. A state Bureau of Criminal Apprehension investigation is underway, and we will spare no resource in bringing those responsible to justice. We will not let fear win."

View CBS News In
CBS News App Open
Chrome Safari Continue
const link = doc.createElement('link'); link.rel = 'stylesheet'; link.href = '/fly/fly/bundles/cbsnewscontent/css/cmp-banner.min.css?v=50747257b890e014813016b79ece0fb2'; doc.head.appendChild(link); doc.body.innerHTML = CONSENT_MESSAGE; } else { el.insertAdjacentHTML('afterend', CONSENT_MESSAGE); } }); } function hidePrivacyMessage() { // Remove from the main document document.querySelectorAll(`.${CONSENT_MESSAGE_CLASS}`).forEach(el => el.remove()); // Remove from inside any iframes document.querySelectorAll('iframe').forEach(iframe => { const doc = iframe.contentDocument || iframe.contentWindow.document; doc.querySelectorAll(`.${CONSENT_MESSAGE_CLASS}`).forEach(el => el.remove()); }); } function activateGatedScripts() { // Handle both new format (cmp-gated-script) and old OneTrust/Ketch format (optanon-category-4) const gatedScripts = Array.from(document.querySelectorAll('script.cmp-gated-script, script.optanon-category-4')); // Activate scripts sequentially with a small delay to avoid timing issues let delay = 0; gatedScripts.forEach(function(placeholder, index) { setTimeout(function() { // Skip if already processed if (placeholder.hasAttribute('data-cmp-processed')) { return; } placeholder.setAttribute('data-cmp-processed', 'true'); const newScript = document.createElement('script'); newScript.type = 'text/javascript'; // Try new format first (data-cmp-src), then fall back to old format (data-src) const src = placeholder.getAttribute('data-cmp-src') || placeholder.getAttribute('data-src'); if (src) { newScript.src = src; } else if (placeholder.textContent) { // Inline script - just copy the content newScript.textContent = placeholder.textContent; } // Handle new format attributes (data-cmp-attrs) - for both inline and external scripts const attrs = placeholder.getAttribute('data-cmp-attrs'); if (attrs) { const tempDiv = document.createElement('div'); tempDiv.innerHTML = '
<\/div>'; const tempAttrs = tempDiv.firstChild.attributes; for (let i = 0; i < tempAttrs.length; i++) { // For external scripts, allow defer/async. For inline scripts, skip them (not valid) if (src || (tempAttrs[i].name !== 'async' && tempAttrs[i].name !== 'defer')) { newScript.setAttribute(tempAttrs[i].name, tempAttrs[i].value); } } } // Copy other attributes from old OneTrust format for (let i = 0; i < placeholder.attributes.length; i++) { const attr = placeholder.attributes[i]; // Skip attributes we've already handled or don't want to copy if (!['class', 'data-src', 'data-type', 'data-cmp-src', 'data-cmp-attrs', 'data-cmp-processed', 'type', 'async', 'defer', 'src'].includes(attr.name)) { newScript.setAttribute(attr.name, attr.value); } } placeholder.parentNode.replaceChild(newScript, placeholder); // If external script, manually trigger window.onload handlers after it loads // This handles widgets that use window.onload for initialization if (src) { newScript.addEventListener('load', function() { // If page already loaded and script set a new onload handler, trigger it if (document.readyState === 'complete' && window.onload) { const originalOnload = window.onload; window.onload = null; // Clear temporarily to prevent loops originalOnload(); // Execute the handler } }); } }, delay); delay += 500; // 500ms delay between each script to allow full loading }); } cbsoptanon.onScriptsReady(function(cmp) { cmp.ot.targetingAllowed(function(allowed) { if (!allowed) { showPrivacyMessage(); } else { activateGatedScripts(); } }); cmp.ot.awaitInitialConsent(function(consent_model) { cmp.ot.addOnConsentChangedHandler(function() { cmp.ot.targetingAllowed(function(allowed) { if (allowed) { hidePrivacyMessage(); activateGatedScripts(); } else { showPrivacyMessage(); } }); }); }); });